Skip to content

Commit

Permalink
fix: removed constants + added docs
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelsalaja committed Oct 6, 2023
1 parent cea7d7f commit 1fecf54
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 71 deletions.
5 changes: 1 addition & 4 deletions Layers/Example/LayerExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ struct LayerExample: View {
if !layers.getCurrentButtons()[1].isEmpty {
LayerButton(text: Binding.constant(layers.getCurrentButtons()[1].keys.first ?? ""),
icon: Binding.constant(layers.getCurrentButtons()[1].values.first ?? ""),
background: .blue,
foregroundColor: .orange
)
background: .blue)
{
layers.next()
}
Expand All @@ -76,7 +74,6 @@ struct LayerExamplePreview: View {
}
}


#Preview() {
ZStack {
Color(.black.opacity(0.25))
Expand Down
45 changes: 26 additions & 19 deletions Layers/Example/LayerExampleComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ struct ExampleIcon: View {
// MARK: - Example Headers

struct ExampleHeader1: View {
@Namespace var namespace
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
HStack {
ExampleIcon(icon: "questionmark")
.matchedGeometryEffect(
id: "layer.icon.left",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)

FullWidthText(center: true) {
Expand All @@ -91,21 +91,21 @@ struct ExampleHeader1: View {
.transition(.scale(scale: 1.0))
.matchedGeometryEffect(
id: "layer.header",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}

ExampleIcon(icon: "xmark")
.matchedGeometryEffect(
id: "layer.icon.right",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
}

struct ExampleHeader2: View {
@Namespace var namespace
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
HStack {
Expand All @@ -117,28 +117,28 @@ struct ExampleHeader2: View {
.transition(.scale(scale: 1.0))
.matchedGeometryEffect(
id: "layer.header",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}

ExampleIcon(icon: "xmark")
.matchedGeometryEffect(
id: "layer.icon.right",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
}

struct ExampleHeader3: View {
@Namespace var namespace
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
HStack {
ExampleIcon(icon: "questionmark")
.matchedGeometryEffect(
id: "layer.icon.left",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)

FullWidthText(center: true) {
Expand All @@ -149,14 +149,14 @@ struct ExampleHeader3: View {
.transition(.scale(scale: 1.0))
.matchedGeometryEffect(
id: "layer.header",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}

ExampleIcon(icon: "xmark")
.matchedGeometryEffect(
id: "layer.icon.right",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
Expand All @@ -165,6 +165,8 @@ struct ExampleHeader3: View {
// MARK: - Example Content

struct ExampleContent1: View {
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
VStack(spacing: 16) {
HStack(alignment: .top) {
Expand Down Expand Up @@ -201,7 +203,7 @@ struct ExampleContent1: View {
.clipShape(RoundedRectangle(cornerRadius: 20))
.matchedGeometryEffect(
id: "layer.content.image.details",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)

Image(.smart)
Expand All @@ -211,7 +213,7 @@ struct ExampleContent1: View {
.transition(.scale(scale: 1.0))
.matchedGeometryEffect(
id: "layer.content.image",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)

HStack(alignment: .top) {
Expand Down Expand Up @@ -240,25 +242,29 @@ struct ExampleContent1: View {
.clipShape(RoundedRectangle(cornerRadius: 20))
.matchedGeometryEffect(
id: "layer.content.recipient",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
}

struct ExampleContent2: View {
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
VStack(spacing: 16) {
ExampleTextField(input: "", placeholder: "Something meaningful...", variation: .extraLarge)
.matchedGeometryEffect(
id: "layer.content.texfield",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
}

struct ExampleContent3: View {
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

var body: some View {
VStack(spacing: 16) {
HStack(alignment: .top) {
Expand Down Expand Up @@ -336,7 +342,7 @@ struct ExampleContent3: View {
.clipShape(RoundedRectangle(cornerRadius: 20))
.matchedGeometryEffect(
id: "layer.content.final",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
Expand All @@ -352,6 +358,8 @@ struct ExampleContent3: View {
// MARK: - Example Buttons

struct LayerButton: View {
@EnvironmentObject var namespaceWrapper: NamespaceWrapper

@Binding var text: String
@Binding var icon: String

Expand Down Expand Up @@ -391,7 +399,7 @@ struct LayerButton: View {
.transition(.opacity)
.matchedGeometryEffect(
id: "layer.button.icon.\(id)",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}

Expand All @@ -401,7 +409,7 @@ struct LayerButton: View {
.transition(.scale(scale: 1.0))
.matchedGeometryEffect(
id: "layer.button.text.\(id)",
in: LayerConstants.namespace
in: namespaceWrapper.namespace
)
}
}
Expand All @@ -424,4 +432,3 @@ struct LayerButton: View {
}
}
}

114 changes: 82 additions & 32 deletions Layers/Source/Layer+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,35 @@
import Foundation
import SwiftUI

struct ScaleButtonStyle: ButtonStyle {
public init() {}

public func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 0.85 : 1)
.transition(.scale(scale: 1.0))
}
}
// MARK: - Views

/// A view that horizontally aligns its content to fill the available width.
///
/// The `FullWidthText` struct is a convenient way to horizontally align text or any other content to fill the entire
/// available width, optionally centering it within the space.
struct FullWidthText: View {
/// The text or content to be displayed and aligned within the view.
@State var text: AnyView

/// A boolean value that determines whether the content should be centered within the available width.
@State var center: Bool

public init<Content>(
/// Initializes a new instance of the `FullWidthText` view.
///
/// - Parameters:
/// - center: A boolean value indicating whether the content should be centered within the available width.
/// - text: A closure that generates the text or content to be displayed within the view.
init<Content>(
center: Bool = false,
@ViewBuilder text: @escaping () -> Content) where Content: View
{
@ViewBuilder text: @escaping () -> Content
) where Content: View {
self.center = center
self.text = AnyView(text())
}

var body: some View {
HStack {
if center {
Spacer()
}
if center { Spacer() }

text

Expand All @@ -44,27 +46,46 @@ struct FullWidthText: View {
}
}

struct ContrastTextColor: ViewModifier {
var background: Color
var light: Color = .white
var dark: Color = .black
var foregroundColor: Color? = nil
// MARK: - Button Styles

func body(content: Content) -> some View {
if let fgColor = foregroundColor {
return content.foregroundColor(fgColor)
} else {
return content.foregroundColor(background.isDark ? light : dark)
}
/// A button style that scales its content when pressed.
///
/// The `ScaleButtonStyle` struct provides a button style that scales down its content when pressed, giving a visual
/// feedback effect to indicate interaction.
public struct ScaleButtonStyle: ButtonStyle {
/// Initializes a new instance of the `ScaleButtonStyle`.
public init() {}

/// Creates the view for the button's body.
///
/// - Parameter configuration: The button's configuration.
/// - Returns: A modified view with the scaling effect applied.
public func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 0.85 : 1)
.transition(.scale(scale: 1.0))
}
}

extension View {
func contrastTextColor(background: Color, light: Color = .white, dark: Color = .black, foregroundColor: Color? = nil) -> some View {
modifier(ContrastTextColor(background: background, light: light, dark: dark, foregroundColor: foregroundColor))
public extension ButtonStyle where Self == ScaleButtonStyle {
/// A convenience property to apply the `ScaleButtonStyle` to a button.
///
/// Use this property to apply the `ScaleButtonStyle` to a button without explicitly creating an instance
/// of the style.
///
/// Example usage:
/// ```
/// Button("Press Me") {
/// // Action to perform when the button is pressed
/// }
/// .buttonStyle(.scale)
/// ```
static var scale: ScaleButtonStyle {
ScaleButtonStyle()
}
}

// MARK: - Modifiers

extension Color {
private enum Luminance {
Expand All @@ -74,6 +95,7 @@ extension Color {
static let threshold: CGFloat = 0.7
}

/// A boolean value indicating whether the color is considered dark based on its luminance.
var isDark: Bool {
var red: CGFloat = 0
var green: CGFloat = 0
Expand All @@ -93,8 +115,36 @@ extension Color {
}
}

extension ButtonStyle where Self == ScaleButtonStyle {
static var scale: ScaleButtonStyle {
ScaleButtonStyle()
/// A view modifier for setting the text color with contrast based on the background color.
struct ContrastTextColor: ViewModifier {
var background: Color
var light: Color = .white
var dark: Color = .black
var foregroundColor: Color? = nil

/// Applies text color contrast based on the background color.
///
/// - Parameter content: The content to which the text color contrast is applied.
/// - Returns: A modified view with the appropriate text color.
func body(content: Content) -> some View {
if let fgColor = foregroundColor {
return content.foregroundColor(fgColor)
} else {
return content.foregroundColor(background.isDark ? light : dark)
}
}
}

extension View {
/// Applies text color contrast based on the background color.
///
/// - Parameters:
/// - background: The background color used to determine text color contrast.
/// - light: The text color to use when the background is considered dark.
/// - dark: The text color to use when the background is considered light.
/// - foregroundColor: An optional text color to use, which takes precedence over automatic contrast calculation.
/// - Returns: A modified view with the appropriate text color contrast applied.
func contrastTextColor(background: Color, light: Color = .white, dark: Color = .black, foregroundColor: Color? = nil) -> some View {
modifier(ContrastTextColor(background: background, light: light, dark: dark, foregroundColor: foregroundColor))
}
}
Loading

0 comments on commit 1fecf54

Please sign in to comment.