Contents

jaywcjlove/colorselector

ColorSelector

Usage

```swift
import ColorSelector

struct ContentView: View {
    @State var color: Color? = .red
    @State var colorClear: Color? = .clear
    @State var nsColor: NSColor? = NSColor.red
    
    var body: some View {
        ColorSelector("Color", selection: $color)
        ColorSelector(selection: $colorClear)
        ColorSelector(nsColor: $nsColor, arrowEdge: .top)
        ColorSelector(selection: $color) {
            Text("Color Picker")
        }
        ColorSelector(selection: $color, footer: {
            Text("Hello World")
        })
        ColorSelector(selection: $color, footer: {
            Text("Hello World")
        }) {
            Text("Color Picker Footer")
        }
        ColorSelector(nsColor: $nsColor, footer: {
            Text("Hello World")
        })
    }
}
```

Using the `swatchColors` environment value, developers can customize the color list in the color selector, replacing the default color options.

```swift
struct ContentView: View {
    @State var color: Color? = .red
    
    var body: some View {
        ColorSelector(selection: $color)
            .environment(\.swatchColors, [
                NSColor(hue: 0.999, saturation: 0.857, brightness: 0.878, alpha: 1.0),
                NSColor(hue: 0.066, saturation: 1.000, brightness: 0.980, alpha: 1.0),
                NSColor(hue: 0.121, saturation: 0.976, brightness: 0.969, alpha: 1.0),
            ])
        ///     
        ColorSelector(selection: $colorClear, arrowEdge: .top)
    }
}
```

By setting the `cornerSize` (corner radius) and `pointSize` (point size) environment values, the corner radius and point size can be dynamically adjusted.

```swift
struct ContentView: View {
    @State var color: Color? = .red
    @State var cornerRadius: CGFloat = 6
    @State var pointSize: CGSize = .init(width: 12, height: 12)
    
    var body: some View {
        ColorSelector(selection: $color)
            .environment(\.cornerSize, cornerRadius)
            .environment(\.pointSize, pointSize)
    }
}
```

**arrowEdge**: The edge of the attachmentAnchor that defines the location of the popover’s arrow. The default is nil, which results in the system allowing any arrow edge.

```swift
import ColorSelector

struct ContentView: View {
    @State var colorClear: Color? = .clear
    
    var body: some View {
        ColorSelector(selection: $colorClear, arrowEdge: .bottom)
    }
}
```

Use the `showsAlpha` modifier to control the visibility of the alpha (opacity) slider in the picker panel.

```swift
import ColorSelector

struct ContentView: View {
    @State var color: Color? = .clear
    
    var body: some View {
        ColorSelector(selection: $color)
            .showsAlpha(false)
    }
}
```

Customize button size using the `controlSize` modifier

```swift
ColorSelector(selection: $color)
    .controlSize(.regular)
```

Set panel size

```swift
ColorSelector(selection: $color)
    .pickerSize(.constant(.init(width: 180, height: 280)))
```

Add content to the bottom of the panel

```swift
ColorSelector(selection: $color, footer: {
    Text("Hello World")
}) {
    Text("Color Picker Footer")
}
```

### ColorSelector Modifier

The `colorSelectorPopover` modifier provides an easy way to add color picker functionality to any view. The modifier attaches a popover that shows when triggered externally.

```swift
struct ContentView: View {
    @State private var backgroundColor: Color? = .blue
    @State private var showColorPicker = false
    
    var body: some View {
        Text("Background Color")
            .padding()
            .background(backgroundColor ?? .clear)
            .onTapGesture {
                showColorPicker = true
            }
            .colorSelectorPopover(
                selection: $backgroundColor,
                isPresented: $showColorPicker
            )
    }
}
```

**Basic usage with external popover control:**

```swift
@State private var textColor: Color? = .primary
@State private var showTextPicker = false

Button("Choose Text Color") {
    showTextPicker = true
}
.colorSelectorPopover(
    selection: $textColor,
    isPresented: $showTextPicker,
    showsAlpha: false
)
```

**Using NSColor binding:**

```swift
@State private var shadowColor: NSColor? = NSColor.gray
@State private var showShadowPicker = false

Text("Shadow Color")
    .onTapGesture { showShadowPicker = true }
    .colorSelectorPopover(
        nsColor: $shadowColor,
        isPresented: $showShadowPicker,
        arrowEdge: .top
    )
```

**Available parameters:**

- `selection`: A binding to the selected Color
- `nsColor`: A binding to the selected NSColor (alternative to selection)
- `isPresented`: A binding to control popover visibility
- `arrowEdge`: The edge where the popover arrow appears (default: system decides)
- `showsAlpha`: Whether to show alpha controls (default: true)

### ColorSelectorButton

The `ColorSelectorButton` is a standalone button component that displays the current selected color and can trigger a popover when tapped. This component provides the visual color representation without the popover functionality built-in.

```swift
struct ContentView: View {
    @State private var selectedColor: Color? = .blue
    @State private var showColorPicker = false
    @State private var buttonSize: ControlSize = .regular
    
    var body: some View {
        VStack(spacing: 20) {
            // Color selector button
            ColorSelectorButton(
                popover: $showColorPicker,
                selection: $selectedColor,
                controlSize: $buttonSize
            )
            
            // Display current color
            Text("Selected: \(selectedColor?.description ?? "None")")
        }
        .colorSelectorPopover(
            selection: $selectedColor,
            isPresented: $showColorPicker
        )
    }
}
```

**Customize button size:**

```swift
@State private var buttonSize: ControlSize = .large

ColorSelectorButton(
    popover: $showColorPicker,
    selection: $selectedColor,
    controlSize: $buttonSize
)
```

**Available control sizes:** `.mini`, `.small`, `.regular`, `.large`, `.extraLarge`

### AlphaSlider

```swift
struct ContentView: View {
    @State var alpha: CGFloat = 1.0
    var saturation: CGFloat = 1.0
    var brightness: CGFloat = 1.0
    var hue: CGFloat = 0.0
    
    var body: some View {
        AlphaSlider(
            alpha: $alpha,
            hue: hue,
            saturation: saturation,
            brightness: brightness
        )
    }
}
```

### ColorSampler

```swift
struct ContentView: View {
    @State var color: Color = Color.red
    var cornerRadius: CGFloat = 6
    var pointSize: CGSize = .init(width: 8, height: 8)
    
    var body: some View {
        ColorSampler(
            color: $color,
            cornerRadius: cornerRadius,
            pointSize: pointSize
        )
    }
}
```

You can customize the width and height of the rectangle using the `rectSize` modifier.

```swift
#Preview {
    @Previewable @State var color: Color? = Color.blue
    ColorSampler(color: $color)
        .rectSize(23)
}
```

### HueSlider

```swift
struct ContentView: View {
    @State var hue: CGFloat = 1
    
    var body: some View {
        HueSlider(hue: $hue)
    }
}
```

### Saturation

```swift
struct ContentView: View {
    @State var saturation: CGFloat = 1.0
    @State var brightness: CGFloat = 1.0
    var hue: CGFloat = 0.0
    
    var body: some View {
        Saturation(
            saturation: $saturation,
            brightness: $brightness,
            hue: hue,
            cornerRadius: 16
        )
    }
}
```

### Swatch

```swift
struct ContentView: View {
    @State var color: NSColor = NSColor.white
    
    var body: some View {
        Swatch()
        Swatch(nsColor: color) { value in
            color = value
        }
    }
}
```

### Sketch

```swift
struct ContentView: View {
    @State var saturation: CGFloat = 1.0
    @State var brightness: CGFloat = 1.0
    @State var hue: CGFloat = 0.0
    @State var alpha: CGFloat = 1.0
    
    var body: some View {
        Sketch(
            hue: $hue,
            saturation: $saturation,
            brightness: $brightness,
            alpha: $alpha
        )
        .frame(width: 180, height: 230)
    }
}
```

License

Licensed under the MIT License.

Package Metadata

Repository: jaywcjlove/colorselector

Default branch: main

README: README.md