๐Ÿ–ผ๏ธSystemColorsView

For preview of other colors, ๐Ÿ‘‰ See: Color+SystemColors.

import SwiftUI
import Colors            // for `Color.standardColors` ...
import DataFlow          // for `ViewPreference`, `view.actOnSelfWidth()`

// โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
// โ”‚    SystemColorsView    โ”‚
// โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

public struct SystemColorsView: View {
    public init(){}
    public var body: some View {
        ScrollView {
            VStack(alignment: .center, spacing: 20){
                
                colorStack("Label Colors", .labelColors)    // ๐ŸŒ€Color + system colors
                colorStack("Fill Colors", .fillColors)
                colorStack("Content Backgrounds", .backgrounds)
                colorStack("Grouped Content Backgrounds", .groupedContentBackgrounds)
                colorStack("Content Colors", .contentColors)
                colorStack("Grayscale", .grayscale)
                
                colorGrid("Standard Colors", .standardColors)
//                colorGrid("Standard Colors", .standardColors.sorted{
//                    $0.hue < $1.hue        // ๐ŸŒ€Color + .hue
//                })
                colorGrid("Standard Colors", .standardColors, hideTitle: true)
                    .padding(2)
                    .background(Color.white)
                    .environment(\.colorScheme, .light)
            }
        }
    }
}

extension SystemColorsView {
    
    @ViewBuilder func colorGrid(
        _ title : String, 
        _ colors: [Color],
        hideTitle: Bool = false
    ) -> some View {
        let adaptive = [GridItem(.adaptive(minimum: 60))]
        VStack(alignment: .center) {
            // color grid title
            if !hideTitle {
                Text(title).font(.title)
            }
            LazyVGrid(columns: adaptive) { 
                ForEach(colors, id: \.self){ Swatch($0) }
            }
        }
    }
    
    // a row of Swatches
    func colorStack(
        _ title : String, 
        _ colors: [Color], 
        spacing : CGFloat? = nil
    ) -> some View 
    {
        VStack(alignment: .center) {
            // title of color stack
            Text(title)
                .font(.title)
            HStack(spacing: spacing) { 
                ForEach(colors, id: \.self){ Swatch($0) } 
            }
        }
    }
}

// โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
// โ”‚    Swatch    โ”‚
// โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

struct Swatch: View {
    
    let color: Color                      // swatch color
    let preferedWidth: CGFloat            // prefered swatch width
    
    // โญ state var without initial value
    @State private var width: CGFloat     // swatch width
    
    var body: some View {
        VStack(alignment: .center, spacing: 4) {
            color
                // โญ swatch width is flexible (height is fixed)
                .frame(width: width, height: preferedWidth)
                .border(Color.separator)
            Text(".\(color.name)")
                .font(.caption2)
                .fixedSize()            // โญ text no wrap
                .padding(.horizontal, 4)
                .actOnSelfWidth {       // ๐ŸŒ€ View + ViewPreference
                    // โญ if text width > prefered width, change swatch watch
                    if $0 > preferedWidth { width = $0 }
                }
        }
        .padding(4)
        .border(Color.separator2)
    }
}

extension Swatch {
    init(_ color: Color, preferedWidth width: CGFloat = 60) {
        self.color = color
        self.preferedWidth = width
        // โญ state var initialized in an init
        //    swatch width = prefered width (at first)
        _width = State(initialValue: width)    
    }
}

Last updated