Skip to content

Commit c2eef53

Browse files
authored
Add isExpanded to Section to replace collapsible (#1497)
* Add `isExpanded` to Section to replace `collapsible` * Add to CHANGELOG --------- Signed-off-by: Carson Katri <[email protected]>
1 parent 158b5dc commit c2eef53

File tree

2 files changed

+51
-27
lines changed

2 files changed

+51
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717

1818
### Changed
1919
- Swift 6 is now required to build LiveView Native applications
20+
- `Section` now uses the `isExpanded` and `phx-change` attributes to enable collapsing in sidebar-styled `List` views
2021

2122
### Fixed
2223

Sources/LiveViewNative/Views/Layout Containers/Collection Containers/Section.swift

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ import SwiftUI
3737
/// </Section>
3838
/// ```
3939
///
40-
/// On macOS, ``ListStyle/sidebar`` can have collapsible sections. Use the ``collapsible`` attribute to make a section collapsible.
40+
/// On macOS, ``ListStyle/sidebar`` can have collapsible sections. Use the ``isExpanded`` attribute to make a section collapsible.
4141
///
4242
/// ```html
43-
/// <Section collapsible>
43+
/// <Section isExpanded={@is_expanded} phx-change="expansion_changed">
4444
/// ...
4545
/// </Section>
4646
/// ```
4747
///
4848
/// ## Attributes
49-
/// * ``collapsible``
49+
/// * ``isExpanded``
5050
///
5151
/// ## Children
5252
/// * `content` - The main body of the section.
@@ -55,34 +55,57 @@ import SwiftUI
5555
@_documentation(visibility: public)
5656
@LiveElement
5757
struct Section<Root: RootRegistry>: View {
58-
/// Enables this section to be collapsed in sidebar lists on macOS.
58+
/// Enables this section to be collapsed in sidebar lists.
5959
@_documentation(visibility: public)
60-
private var collapsible: Bool = false
60+
@ChangeTracked(attribute: .init(name: "isExpanded"))
61+
private var isExpanded: Bool? = nil
6162

62-
public var body: some View {
63-
SwiftUI.Section {
64-
let elements = $liveElement.childNodes(in: "content", default: true)
65-
.map { (node) -> ForEachElement in
66-
if let element = node.asElement(),
67-
let id = element.attributeValue(for: .init(name: "id"))
68-
{
69-
return .keyed(node, id: id)
70-
} else {
71-
return .unkeyed(node)
72-
}
63+
var content: some View {
64+
let elements = $liveElement.childNodes(in: "content", default: true)
65+
.map { (node) -> ForEachElement in
66+
if let element = node.asElement(),
67+
let id = element.attributeValue(for: .init(name: "id"))
68+
{
69+
return .keyed(node, id: id)
70+
} else {
71+
return .unkeyed(node)
7372
}
74-
ForEach(elements) { childNode in
75-
ViewTreeBuilder<Root>.NodeView(node: childNode.node, context: $liveElement.context.storage)
76-
.trackListItemScrollOffset(id: childNode.id)
7773
}
78-
} header: {
79-
$liveElement.children(in: "header")
80-
} footer: {
81-
$liveElement.children(in: "footer")
74+
return ForEach(elements) { childNode in
75+
ViewTreeBuilder<Root>.NodeView(node: childNode.node, context: $liveElement.context.storage)
76+
.trackListItemScrollOffset(id: childNode.id)
77+
}
78+
}
79+
80+
var header: some View {
81+
$liveElement.children(in: "header")
82+
}
83+
84+
var footer: some View {
85+
$liveElement.children(in: "footer")
86+
}
87+
88+
public var body: some View {
89+
if isExpanded != nil,
90+
#available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, visionOS 1.0, *)
91+
{
92+
SwiftUI.Section(isExpanded: Binding {
93+
isExpanded ?? false
94+
} set: {
95+
isExpanded = $0
96+
}) {
97+
content
98+
} header: {
99+
header
100+
}
101+
} else {
102+
SwiftUI.Section {
103+
content
104+
} header: {
105+
header
106+
} footer: {
107+
footer
108+
}
82109
}
83-
#if os(macOS)
84-
.collapsible(collapsible)
85-
#endif
86-
87110
}
88111
}

0 commit comments

Comments
 (0)