Skip to content

Commit 09ab9a2

Browse files
authored
Merge pull request #772 from JPToroDev/grid
Add `alignment` parameter to `Grid`.
2 parents 4ef4789 + 976168b commit 09ab9a2

File tree

6 files changed

+65
-37
lines changed

6 files changed

+65
-37
lines changed

Sources/Ignite/Elements/Grid.swift

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,50 +28,78 @@ public struct Grid: HTML, HorizontalAligning {
2828
/// The amount of space between elements.
2929
private var spacingAmount: SpacingType = .semantic(.none)
3030

31+
/// The alignment of the items within the grid.
32+
private var alignment: Alignment = .center
33+
3134
/// The items to display in this grid.
3235
private var items: HTMLCollection
3336

3437
/// Creates a new `Grid` object using a block element builder
3538
/// that returns an array of items to use in this grid.
3639
/// - Parameters:
40+
/// - alignment: The alignment of items in the grid. Defaults to `.center`.
3741
/// - spacing: The number of pixels between each element.
3842
/// - items: The items to use in this grid.
39-
public init(spacing: Int, @HTMLBuilder items: () -> some HTML) {
43+
public init(
44+
alignment: Alignment = .center,
45+
spacing: Int,
46+
@HTMLBuilder items: () -> some HTML
47+
) {
4048
self.items = HTMLCollection(items)
49+
self.alignment = alignment
4150
self.spacingAmount = .exact(spacing)
4251
}
4352

4453
/// Creates a new `Grid` object using a block element builder
4554
/// that returns an array of items to use in this grid.
4655
/// - Parameters:
56+
/// - alignment: The alignment of items in the grid. Defaults to `.center`.
4757
/// - spacing: The predefined size between each element. Defaults to `.none`.
4858
/// - items: The items to use in this grid.
49-
public init(spacing: SpacingAmount = .medium, @HTMLBuilder items: () -> some HTML) {
59+
public init(
60+
alignment: Alignment = .center,
61+
spacing: SpacingAmount = .medium,
62+
@HTMLBuilder items: () -> some HTML
63+
) {
5064
self.items = HTMLCollection(items)
65+
self.alignment = alignment
5166
self.spacingAmount = .semantic(spacing)
5267
}
5368

5469
/// Creates a new grid from a collection of items, along with a function that converts
5570
/// a single object from the collection into one grid column.
5671
/// - Parameters:
5772
/// - items: A sequence of items you want to convert into columns.
73+
/// - alignment: The alignment of items in the grid. Defaults to `.center`.
5874
/// - spacing: The number of pixels between each element.
5975
/// - content: A function that accepts a single value from the sequence, and
6076
/// returns a some HTML representing that value in the grid.
61-
public init<T>(_ items: any Sequence<T>, spacing: Int, content: (T) -> some HTML) {
77+
public init<T>(
78+
_ items: any Sequence<T>,
79+
alignment: Alignment = .center,
80+
spacing: Int, content: (T) -> some HTML
81+
) {
6282
self.items = HTMLCollection(items.map(content))
83+
self.alignment = alignment
6384
self.spacingAmount = .exact(spacing)
6485
}
6586

6687
/// Creates a new grid from a collection of items, along with a function that converts
6788
/// a single object from the collection into one grid column.
6889
/// - Parameters:
6990
/// - items: A sequence of items you want to convert into columns.
91+
/// - alignment: The alignment of items in the grid. Defaults to `.center`.
7092
/// - spacing: The predefined size between each element. Defaults to `.none`
7193
/// - content: A function that accepts a single value from the sequence, and
7294
/// returns a some HTML representing that value in the grid.
73-
public init<T>(_ items: any Sequence<T>, spacing: SpacingAmount = .medium, content: (T) -> some HTML) {
95+
public init<T>(
96+
_ items: any Sequence<T>,
97+
alignment: Alignment = .center,
98+
spacing: SpacingAmount = .medium,
99+
content: (T) -> some HTML
100+
) {
74101
self.items = HTMLCollection(items.map(content))
102+
self.alignment = alignment
75103
self.spacingAmount = .semantic(spacing)
76104
}
77105

@@ -88,6 +116,7 @@ public struct Grid: HTML, HorizontalAligning {
88116
/// - Returns: The HTML for this element.
89117
public func render() -> String {
90118
var gridAttributes = attributes.appending(classes: ["row"])
119+
gridAttributes.append(classes: alignment.horizontal.containerAlignmentClass)
91120

92121
// If a column count is set, we want to use that for all
93122
// page sizes that are medium and above. Below that we
@@ -138,6 +167,7 @@ public struct Grid: HTML, HorizontalAligning {
138167

139168
return Section(item)
140169
.class(name ?? "col")
170+
.class(alignment.vertical.itemAlignmentClass)
141171
}
142172

143173
/// Renders a group of HTML elements with consistent styling and attributes.

Sources/Ignite/Elements/HStack.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,3 @@ public struct HStack: HTML {
8080
return "<div\(attributes)>\(content)</div>"
8181
}
8282
}
83-
84-
private extension VerticalAlignment {
85-
/// The Bootstrap alignment class for items within a flexbox
86-
var itemAlignmentClass: String {
87-
switch self {
88-
case .top: "align-self-start"
89-
case .center: "align-self-center"
90-
case .bottom: "align-self-end"
91-
}
92-
}
93-
}

Sources/Ignite/Modifiers/HorizontalAlignment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public enum HorizontalAlignment: String, Sendable, Equatable {
4646
case trailing = "text-end"
4747

4848
/// The Bootstrap class for flex justify-content alignment
49-
var flexAlignmentClass: String {
49+
var containerAlignmentClass: String {
5050
switch self {
5151
case .leading: "justify-content-start"
5252
case .center: "justify-content-center"

Sources/Ignite/Types/Alignment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public struct Alignment: Equatable {
5151
extension Alignment {
5252
/// The appropriate Bootstrap classes for this alignment
5353
var bootstrapClasses: [String] {
54-
[horizontal.flexAlignmentClass, vertical.flexAlignmentClass]
54+
[horizontal.containerAlignmentClass, vertical.containerAlignmentClass]
5555
}
5656

5757
/// Flex container rules for aligning content

Sources/Ignite/Types/VerticalAlignment.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,21 @@ public enum VerticalAlignment: Equatable, Sendable {
1414
/// Align content to the bottom
1515
case bottom
1616

17-
/// The Bootstrap class that implements this alignment
18-
var flexAlignmentClass: String {
17+
/// The Bootstrap class for the container with this alignment
18+
var containerAlignmentClass: String {
1919
switch self {
2020
case .top: "align-items-start"
2121
case .center: "align-items-center"
2222
case .bottom: "align-items-end"
2323
}
2424
}
25+
26+
/// The Bootstrap class applied to items inside a container
27+
var itemAlignmentClass: String {
28+
switch self {
29+
case .top: "align-self-start"
30+
case .center: "align-self-center"
31+
case .bottom: "align-self-end"
32+
}
33+
}
2534
}

Tests/IgniteTesting/Elements/Grid.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ class GridTests: IgniteTestSuite {
3030
let output = element.render()
3131

3232
#expect(output == """
33-
<div class="row">\
34-
<div class="col g-3">\
33+
<div class="row justify-content-center">\
34+
<div class="col align-self-center g-3">\
3535
<img src="/images/photos/shades.jpg" alt="A pair of sunglasses." class="img-fluid" />\
3636
</div>\
37-
<div class="col g-3">\
37+
<div class="col align-self-center g-3">\
3838
<img src="/images/photos/stack.jpg" alt="A door partly open." class="img-fluid" />\
3939
</div>\
40-
<div class="col g-3">\
40+
<div class="col align-self-center g-3">\
4141
<img src="/images/photos/wind.jpg" alt="A windy day." class="img-fluid" />\
4242
</div>\
4343
</div>
@@ -63,13 +63,13 @@ class GridTests: IgniteTestSuite {
6363
let output = element.render()
6464

6565
#expect(output == """
66-
<div class="row">\
67-
<div class="col-md-4 g-3">\
66+
<div class="row justify-content-center">\
67+
<div class="col-md-4 align-self-center g-3">\
6868
<img src="/images/photos/shades.jpg" alt="A pair of sunglasses." class="img-fluid" />\
6969
</div>\
70-
<div class="col-md-4 g-3"><img src="/images/photos/stack.jpg" alt="A door partly open." class="img-fluid" />\
70+
<div class="col-md-4 align-self-center g-3"><img src="/images/photos/stack.jpg" alt="A door partly open." class="img-fluid" />\
7171
</div>\
72-
<div class="col-md-4 g-3">\
72+
<div class="col-md-4 align-self-center g-3">\
7373
<img src="/images/photos/wind.jpg" alt="A windy day." class="img-fluid" />\
7474
</div>\
7575
</div>
@@ -99,16 +99,16 @@ class GridTests: IgniteTestSuite {
9999
let output = element.render()
100100

101101
#expect(output == """
102-
<div class="row">\
103-
<div class="col-md-4 g-3">\
102+
<div class="row justify-content-center">\
103+
<div class="col-md-4 align-self-center g-3">\
104104
<img src="/images/photos/shades.jpg" alt="A pair of sunglasses." class="img-fluid" />\
105105
</div>\
106-
<div class="col-md-4 g-3">\
106+
<div class="col-md-4 align-self-center g-3">\
107107
<img src="/images/photos/stack.jpg" alt="A door partly open." class="img-fluid" />\
108108
</div>\
109-
<div class="col-md-4 g-3"><img src="/images/photos/rug.jpg" alt="A nice rug." class="img-fluid" />\
109+
<div class="col-md-4 align-self-center g-3"><img src="/images/photos/rug.jpg" alt="A nice rug." class="img-fluid" />\
110110
</div>\
111-
<div class="col-md-4 g-3">\
111+
<div class="col-md-4 align-self-center g-3">\
112112
<img src="/images/photos/car.jpg" alt="The window of a car." class="img-fluid" />\
113113
</div>\
114114
</div>
@@ -135,17 +135,17 @@ class GridTests: IgniteTestSuite {
135135
let output = element.render()
136136

137137
#expect(output == """
138-
<div class="row row-cols-1 row-cols-md-2">\
139-
<div class="col g-3">\
138+
<div class="row justify-content-center row-cols-1 row-cols-md-2">\
139+
<div class="col align-self-center g-3">\
140140
<img src="/images/photos/shades.jpg" alt="A pair of sunglasses." class="img-fluid" />\
141141
</div>\
142-
<div class="col g-3">\
142+
<div class="col align-self-center g-3">\
143143
<img src="/images/photos/stack.jpg" alt="A door partly open." class="img-fluid" />\
144144
</div>\
145-
<div class="col g-3">\
145+
<div class="col align-self-center g-3">\
146146
<img src="/images/photos/rug.jpg" alt="A nice rug." class="img-fluid" />\
147147
</div>\
148-
<div class="col g-3"><img src="/images/photos/car.jpg" alt="The window of a car." class="img-fluid" />\
148+
<div class="col align-self-center g-3"><img src="/images/photos/car.jpg" alt="The window of a car." class="img-fluid" />\
149149
</div>\
150150
</div>
151151
""")

0 commit comments

Comments
 (0)