-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Part of #51.
- Loading branch information
Showing
8 changed files
with
166 additions
and
2 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
...Documentation.docc/Views/TailwindCSS/Backgrounds/Backgrounds-BackgroundImage.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Background image | ||
|
||
Utilities for controlling the background image of a view. | ||
|
||
## Topics | ||
|
||
### Modifiers | ||
|
||
- ``View/backgroundImage(_:size:repeat:condition:)`` | ||
|
||
### Supporting types | ||
|
||
- ``BackgroundRepeat`` | ||
- ``BackgroundSize`` | ||
- ``Size`` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
Sources/Slipstream/TailwindCSS/Backgrounds/View+backgroundImage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import Foundation | ||
|
||
/// Constants that control the repitition of a background image.. | ||
/// | ||
/// - SeeAlso: Tailwind CSS' [`background repeat`](https://tailwindcss.com/docs/background-repeat) documentation. | ||
@available(iOS 17.0, macOS 14.0, *) | ||
public enum BackgroundRepeat: String { | ||
case yes = "repeat" | ||
case no = "no-repeat" | ||
case x = "repeat-x" | ||
case y = "repeat-y" | ||
case round = "repeat-round" | ||
case space = "repeat-space" | ||
} | ||
|
||
/// Constants that control the size of a background image.. | ||
/// | ||
/// - SeeAlso: Tailwind CSS' [`background size`](https://tailwindcss.com/docs/background-size) documentation. | ||
@available(iOS 17.0, macOS 14.0, *) | ||
public struct BackgroundSize { | ||
/// Displays the background image at its default size. | ||
public static let auto: BackgroundSize = BackgroundSize(storage: .aspectRatio(.auto)) | ||
|
||
/// Scales the background image until it fills the background layer. | ||
public static let cover: BackgroundSize = BackgroundSize(storage: .aspectRatio(.cover)) | ||
|
||
/// Scales the background image to the outer edges without cropping or stretching. | ||
public static let contain: BackgroundSize = BackgroundSize(storage: .aspectRatio(.contain)) | ||
|
||
/// Specifies an arbitrary size to use for the background image. | ||
public static func size(width: Double, height: Double) -> BackgroundSize { | ||
return BackgroundSize( | ||
storage: .size(.init(width: width, height: height)) | ||
) | ||
} | ||
|
||
fileprivate init(storage: Storage) { | ||
self.storage = storage | ||
} | ||
|
||
fileprivate enum AspectRatio: String { | ||
case auto | ||
case cover | ||
case contain | ||
} | ||
fileprivate enum Storage { | ||
case aspectRatio(AspectRatio) | ||
case size(Size) | ||
} | ||
fileprivate let storage: Storage | ||
|
||
fileprivate func toTailwindSpacingClass() -> String? { | ||
switch storage { | ||
case .aspectRatio(let aspectRatio): | ||
return "bg-" + aspectRatio.rawValue | ||
case .size(let size): | ||
guard let pixels = size.asPixels else { | ||
return nil | ||
} | ||
return "bg-[length:\(pixels)]" | ||
} | ||
} | ||
} | ||
|
||
extension View { | ||
/// Changes the background image of the view. | ||
/// | ||
/// - SeeAlso: Tailwind CSS' [`background image`](https://tailwindcss.com/docs/background-image) documentation. | ||
/// - SeeAlso: Tailwind CSS' [`background repeat`](https://tailwindcss.com/docs/background-repeat) documentation. | ||
/// - SeeAlso: Tailwind CSS' [`background size`](https://tailwindcss.com/docs/background-size) documentation. | ||
@available(iOS 17.0, macOS 14.0, *) | ||
public func backgroundImage(_ url: URL?, size: BackgroundSize? = nil, repeat: BackgroundRepeat? = nil, condition: Condition? = nil) -> some View { | ||
var classNames: [String] = [] | ||
if let url { | ||
classNames.append("bg-[url('\(url.path())')]") | ||
} | ||
if let size = size?.toTailwindSpacingClass() { | ||
classNames.append(size) | ||
} | ||
if let `repeat` { | ||
classNames.append("bg-\(`repeat`.rawValue)") | ||
} | ||
return modifier(TailwindClassModifier(add: Set(classNames), condition: condition)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Foundation | ||
|
||
/// A structure that represents the edges of a rectangle, used for specifying | ||
/// which sides to apply modifications to, such as padding or margin. | ||
/// | ||
/// You'll typically work with a set of edges using the ``Edge/Set`` type. | ||
@available(iOS 17.0, macOS 14.0, *) | ||
public struct Size { | ||
/// Creates a size. | ||
/// | ||
/// - Parameters: | ||
/// - width: The width, in points. | ||
/// - height: The height, in points. | ||
public init(width: Double, height: Double) { | ||
self.width = width | ||
self.height = height | ||
} | ||
|
||
let width: Double | ||
let height: Double | ||
|
||
var asPixels: String? { | ||
let formatter = NumberFormatter() | ||
formatter.maximumFractionDigits = 2 | ||
guard let width = formatter.string(from: width as NSNumber), | ||
let height = formatter.string(from: height as NSNumber) else { | ||
return nil | ||
} | ||
return "\(width)px_\(height)px" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
Tests/SlipstreamTests/TailwindCSS/Backgrounds/BackgroundImageTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import Foundation | ||
import Testing | ||
|
||
import Slipstream | ||
|
||
struct BackgroundImageTests { | ||
@Test func justURL() throws { | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"))) == #"<div class="bg-[url('/logo.png')]"></div>"#) | ||
} | ||
|
||
@Test func withRepeat() throws { | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .no)) == #"<div class="bg-[url('/logo.png')] bg-no-repeat"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .yes)) == #"<div class="bg-[url('/logo.png')] bg-repeat"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .x)) == #"<div class="bg-[url('/logo.png')] bg-repeat-x"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .y)) == #"<div class="bg-[url('/logo.png')] bg-repeat-y"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .round)) == #"<div class="bg-[url('/logo.png')] bg-repeat-round"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), repeat: .space)) == #"<div class="bg-[url('/logo.png')] bg-repeat-space"></div>"#) | ||
} | ||
|
||
@Test func withSize() throws { | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), size: .auto)) == #"<div class="bg-[url('/logo.png')] bg-auto"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), size: .contain)) == #"<div class="bg-[url('/logo.png')] bg-contain"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), size: .cover)) == #"<div class="bg-[url('/logo.png')] bg-cover"></div>"#) | ||
try #expect(renderHTML(Div {}.backgroundImage(URL(string: "/logo.png"), size: .size(width: 100, height: 50))) == #"<div class="bg-[length:100px_50px] bg-[url('/logo.png')]"></div>"#) | ||
} | ||
} |