Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
claudioitalian12 committed Jun 5, 2022
0 parents commit a86e8ba
Show file tree
Hide file tree
Showing 14 changed files with 439 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
92 changes: 92 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/StyleInjection.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1330"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StyleInjection"
BuildableName = "StyleInjection"
BlueprintName = "StyleInjection"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StyleInjectionTests"
BuildableName = "StyleInjectionTests"
BlueprintName = "StyleInjectionTests"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StyleInjectionTests"
BuildableName = "StyleInjectionTests"
BlueprintName = "StyleInjectionTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StyleInjection"
BuildableName = "StyleInjection"
BlueprintName = "StyleInjection"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
28 changes: 28 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "StyleInjection",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "StyleInjection",
targets: ["StyleInjection"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "StyleInjection",
dependencies: []),
.testTarget(
name: "StyleInjectionTests",
dependencies: ["StyleInjection"]),
]
)
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# StyleInjection

A description of this package.
56 changes: 56 additions & 0 deletions Sources/StyleInjection/StyleInjection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Foundation
import UIKit

// MARK: - StyleInjection.
public protocol StyleInjection {
/// Apply this style to a UIView.
///
/// - Parameter style: the function to style
func applyStyle<View: UIView>(to view: View)

/// Apply this style to multiple views.
///
/// - Parameter views: the views to style
func applyStyle<View: UIView>(to view: View...)
}

public extension StyleInjection {
/// Static instance of UIViewStyle.
static var stylizable: Stylizable<Self> { Stylizable() }
}

// MARK: - StyleInjection.
public extension StyleInjection {
/// Apply value from keypath.
///
/// - Parameter keyPath: the views keypath
/// - Parameter newValue: the value of keypath
@discardableResult
func set<Value>(_ keyPath:ReferenceWritableKeyPath<Self, Value>,to newValue: Value) -> Self {
self[keyPath: keyPath] = newValue
return self
}

/// Apply value from keypath.
///
/// - Parameter keyPath: the views keypath
/// - Parameter newValue: the value of keypath
@discardableResult
mutating func set<Value>(_ keyPath:WritableKeyPath<Self, Value>,to newValue: Value) -> Self {
self[keyPath: keyPath] = newValue
return self
}
}

// MARK: - UIView.
extension UIView: StyleInjection {
/// Apply this style to a UIView.
///
/// - Parameter style: the function to style
public func applyStyle<View>(to view: View) { }

/// Apply this style to multiple views.
///
/// - Parameter views: the views to style
public func applyStyle<View>(to view: View...) { }
}
15 changes: 15 additions & 0 deletions Sources/StyleInjection/StyleInjectionGroup.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// File.swift
//
//
// Created by Claudio Cavalli on 29/05/22.
//

import Foundation
import UIKit

// MARK: - StyleInjectionGroup.
public protocol StyleInjectionGroup {
func getStylizable(key: StyleInjectionKey) -> StyleInjection?
func applyStyle<View: UIView>(key: StyleInjectionKey, view: View)
}
60 changes: 60 additions & 0 deletions Sources/StyleInjection/StyleInjectionGroupBuilder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// File.swift
//
//
// Created by Claudio Cavalli on 29/05/22.
//

import Foundation
import UIKit

// MARK: - Array StyleInjectionGroup.
extension Array: StyleInjectionGroup where Element == StylizableGroup {
public func getStylizable(key: StyleInjectionKey) -> StyleInjection? {
self.first {
$0.getStylizable(key: key) != nil
}?.stylizable?.1
}

public func applyStyle<View: UIView>(key: StyleInjectionKey, view: View) {
guard let stylizable = getStylizable(key: key) else { return }

stylizable.applyStyle(to: view)
}

public var stylizable: [StylizableGroup] { self }
}

extension Array where Element == StyleInjectionGroup {
public func getStylizable(key: StyleInjectionKey) -> StyleInjection? {
(self.first {
$0.getStylizable(key: key) != nil
} as? StylizableGroup)?.stylizable?.1
}

public func applyStyle<View: UIView>(key: StyleInjectionKey, view: View) {
guard let stylizable = getStylizable(key: key) else { return }

stylizable.applyStyle(to: view)
}
}

// MARK: - StyleInjectionGroupBuilder.
@resultBuilder
public struct StyleInjectionGroupBuilder {
public static func buildBlock(_ group: StylizableGroup...) -> [StyleInjectionGroup] {
group.compactMap { $0 }
}

public static func buildOptional(_ group: [StylizableGroup]?) -> [StyleInjectionGroup] {
group?.compactMap { $0 } ?? []
}

public static func buildEither(first group: [StylizableGroup]) -> [StyleInjectionGroup] {
group.compactMap { $0 }
}

public static func buildEither(second group: [StylizableGroup]) -> [StyleInjectionGroup] {
group.compactMap { $0 }
}
}
13 changes: 13 additions & 0 deletions Sources/StyleInjection/StyleInjectionGroupFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// File.swift
//
//
// Created by Claudio Cavalli on 29/05/22.
//

import Foundation

// MARK: - StyleInjectionGroupFactory.
public protocol StyleInjectionGroupFactory {
associatedtype StyleKey: RawRepresentable where StyleKey.RawValue: StringProtocol
}
13 changes: 13 additions & 0 deletions Sources/StyleInjection/StyleInjectionKey.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// File.swift
//
//
// Created by Claudio Cavalli on 29/05/22.
//

import Foundation

// MARK: - StyleInjectionKey.
public protocol StyleInjectionKey {
var keyValue: String { get }
}
40 changes: 40 additions & 0 deletions Sources/StyleInjection/Stylizable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// File.swift
//
//
// Created by Claudio Cavalli on 29/05/22.
//

import Foundation

// MARK: - Stylizable.
public struct Stylizable<ViewStyle>: StyleInjection {
/// The styling function that takes a `UIView` instance
/// and performs side-effects on it.
public var style: ((ViewStyle)-> Void)?

/// Build a UIViewStyle with style.
///
/// - Parameter style: the function to style
public func buildStyle(style: ((ViewStyle)-> Void)?) -> StyleInjection {
Stylizable(style: style)
}

/// Apply this style to a UIView.
///
/// - Parameter view: the view to style
public func applyStyle<View>(to view: View) {
guard let view = view as? ViewStyle else { return }
style?(view)
}

/// Apply this style to multiple views.
///
/// - Parameter views: the views to style
public func applyStyle<View>(to views: View...) {
views.forEach { view in
applyStyle(to: view)
}
}
}

Loading

0 comments on commit a86e8ba

Please sign in to comment.