From e1fa0d70b353c7c2eef910bbfa06807514f15af3 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Fri, 9 Aug 2024 23:11:51 -0400 Subject: [PATCH] Add position modifier. (#139) Part of https://github.com/jverkoey/slipstream/issues/51. --- .../SlipstreamForTailwindCSSDevelopers.md | 2 +- .../TailwindCSS/Layout/Layout-Position.md | 13 ++++ .../TailwindCSS/TailwindCSS-Utilities.md | 1 + .../TailwindCSS/Layout/View+position.swift | 62 +++++++++++++++++++ .../TailwindCSS/Layout/PositionTests.swift | 12 ++++ 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Sources/Slipstream/Documentation.docc/TailwindCSS/Layout/Layout-Position.md create mode 100644 Sources/Slipstream/TailwindCSS/Layout/View+position.swift create mode 100644 Tests/SlipstreamTests/TailwindCSS/Layout/PositionTests.swift diff --git a/Sources/Slipstream/Documentation.docc/Guides/SlipstreamForTailwindCSSDevelopers.md b/Sources/Slipstream/Documentation.docc/Guides/SlipstreamForTailwindCSSDevelopers.md index d304729..e24adc4 100644 --- a/Sources/Slipstream/Documentation.docc/Guides/SlipstreamForTailwindCSSDevelopers.md +++ b/Sources/Slipstream/Documentation.docc/Guides/SlipstreamForTailwindCSSDevelopers.md @@ -27,7 +27,7 @@ Tailwind utility | Slipstream modifier [Object Position](https://tailwindcss.com/docs/object-position) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) [Overflow](https://tailwindcss.com/docs/overflow) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) [Overscroll Behavior](https://tailwindcss.com/docs/overscroll-behavior) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) -[Position](https://tailwindcss.com/docs/position) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) +[Position](https://tailwindcss.com/docs/position) | ``View/position(_:condition:)`` [Top / Right / Bottom / Left](https://tailwindcss.com/docs/top-right-bottom-left) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) [Visibility](https://tailwindcss.com/docs/visibility) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) [Z-Index](https://tailwindcss.com/docs/z-index) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/51) diff --git a/Sources/Slipstream/Documentation.docc/TailwindCSS/Layout/Layout-Position.md b/Sources/Slipstream/Documentation.docc/TailwindCSS/Layout/Layout-Position.md new file mode 100644 index 0000000..90fae5f --- /dev/null +++ b/Sources/Slipstream/Documentation.docc/TailwindCSS/Layout/Layout-Position.md @@ -0,0 +1,13 @@ +# Position + +Utilities for controlling how a view is positioned in the DOM. + +## Topics + +### Modifiers + +- ``View/position(_:condition:)`` + +### Supporting types + +- ``Position`` diff --git a/Sources/Slipstream/Documentation.docc/TailwindCSS/TailwindCSS-Utilities.md b/Sources/Slipstream/Documentation.docc/TailwindCSS/TailwindCSS-Utilities.md index c2d2278..e7dbac9 100644 --- a/Sources/Slipstream/Documentation.docc/TailwindCSS/TailwindCSS-Utilities.md +++ b/Sources/Slipstream/Documentation.docc/TailwindCSS/TailwindCSS-Utilities.md @@ -9,6 +9,7 @@ Slipstream implementations of Tailwind CSS's utility classes. - ``Container`` - - +- ### Flexbox & Grid diff --git a/Sources/Slipstream/TailwindCSS/Layout/View+position.swift b/Sources/Slipstream/TailwindCSS/Layout/View+position.swift new file mode 100644 index 0000000..93c2a38 --- /dev/null +++ b/Sources/Slipstream/TailwindCSS/Layout/View+position.swift @@ -0,0 +1,62 @@ +/// Constants that control how a view is positioned in the DOM +/// +/// - SeeAlso: Tailwind CSS' [position](https://tailwindcss.com/docs/position) documentation. +@available(iOS 17.0, macOS 14.0, *) +public enum Position: String { + + /// Positions a view according to the normal flow of the document. + /// + /// Any offsets will be ignored and the view will not act as a + /// position reference for absolutely positioned children. + /// + /// - SeeAlso: Tailwind CSS' [static positioning](https://tailwindcss.com/docs/position#statically-positioning-elements) documentation. + case `static` + + /// Positions a view relative to the browser window. + /// + /// Any offsets are calculated relative to the viewport and the + /// view will act as a position reference for absolutely positioned + /// children. + /// + /// - SeeAlso: Tailwind CSS' [fixed positioning](https://tailwindcss.com/docs/position#fixed-positioning-elements) documentation. + case fixed + + /// Positions a view outside of the normal flow of the document, + /// causing neighboring views to act as if the view doesn’t exist. + /// + /// Any offsets are calculated relative to the nearest parent that + /// has a position other than static, and the view will act as + /// a position reference for other absolutely positioned children. + /// + /// - SeeAlso: Tailwind CSS' [absolute positioning](https://tailwindcss.com/docs/position#absolutely-positioning-elements) documentation. + case absolute + + /// Positions an element according to the normal flow of the document. + /// + /// Any offsets are calculated relative to the view's normal + /// position and the view will act as a position reference for + /// absolutely positioned children. + /// + /// - SeeAlso: Tailwind CSS' [relative positioning](https://tailwindcss.com/docs/position#relatively-positioning-elements) documentation. + case relative + + /// Positions a view as relative until it crosses a specified + /// threshold, then treats it as fixed until its parent is off screen. + /// + /// Any offsets are calculated relative to the view's normal position + /// and the view will act as a position reference for absolutely + /// positioned children. + /// + /// - SeeAlso: Tailwind CSS' [sticky positioning](https://tailwindcss.com/docs/position#sticky-positioning-elements) documentation. + case sticky +} + +extension View { + /// Changes how a view is positioned in the DOM. + /// + /// - SeeAlso: Tailwind CSS' [position](https://tailwindcss.com/docs/position) documentation. + @available(iOS 17.0, macOS 14.0, *) + public func position(_ position: Position, condition: Condition? = nil) -> some View { + return modifier(TailwindClassModifier(add: position.rawValue, condition: condition)) + } +} diff --git a/Tests/SlipstreamTests/TailwindCSS/Layout/PositionTests.swift b/Tests/SlipstreamTests/TailwindCSS/Layout/PositionTests.swift new file mode 100644 index 0000000..39bd509 --- /dev/null +++ b/Tests/SlipstreamTests/TailwindCSS/Layout/PositionTests.swift @@ -0,0 +1,12 @@ +import Testing +import Slipstream + +struct PositionTests { + @Test func enumeration() throws { + try #expect(renderHTML(Div {}.position(.static)) == #"
"#) + try #expect(renderHTML(Div {}.position(.fixed)) == #"
"#) + try #expect(renderHTML(Div {}.position(.absolute)) == #"
"#) + try #expect(renderHTML(Div {}.position(.relative)) == #"
"#) + try #expect(renderHTML(Div {}.position(.sticky)) == #"
"#) + } +}