Implement `SidebarListStyle` (#210)
First pass at the SidebarListStyle. For this to be truly complete, work needs to be completed on ButtonStyles. I can look at that next. NavigationLinks in a Sidebar are Text items that draw a blue background when clicked (and perhaps when item is active.) Co-authored-by: Gene Z. Ragan <diskzero@mac.com> Co-authored-by: Jed Fox <git@jedfox.com> Co-authored-by: Gene Ragan <gene@semitone.audio>
This commit is contained in:
parent
f5af009db2
commit
8041732dc9
|
@ -7,6 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3DCDE44424CA6AD400910F17 /* SidebarDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */; };
|
||||
3DCDE44524CA6AD400910F17 /* SidebarDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */; };
|
||||
854A1A9124B3E3630027BC32 /* ToggleDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */; };
|
||||
854A1A9324B3F28F0027BC32 /* ToggleDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */; };
|
||||
85ED186A24AD38F20085DFA0 /* UIAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85ED186924AD38F20085DFA0 /* UIAppDelegate.swift */; };
|
||||
|
@ -76,6 +78,7 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SidebarDemo.swift; sourceTree = "<group>"; };
|
||||
85CBD5DE24B3BF090066468A /* ToggleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleDemo.swift; sourceTree = "<group>"; };
|
||||
85ED184A24AD379A0085DFA0 /* TokamakDemo Native.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TokamakDemo Native.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
85ED185224AD379A0085DFA0 /* TokamakDemo Native.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TokamakDemo Native.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -160,20 +163,21 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */,
|
||||
D1EE7EA624C0DD2100C0D127 /* PickerDemo.swift */,
|
||||
B56F22DF24BC89FD001738DF /* ColorDemo.swift */,
|
||||
85ED189E24AD425E0085DFA0 /* Counter.swift */,
|
||||
85ED18A024AD425E0085DFA0 /* EnvironmentDemo.swift */,
|
||||
85ED189C24AD425E0085DFA0 /* ForEachDemo.swift */,
|
||||
B56F22E224BD1C26001738DF /* GridDemo.swift */,
|
||||
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */,
|
||||
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */,
|
||||
B51F214F24B920B400CF2583 /* PathDemo.swift */,
|
||||
D1EE7EA624C0DD2100C0D127 /* PickerDemo.swift */,
|
||||
3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */,
|
||||
85ED189A24AD425E0085DFA0 /* SpacerDemo.swift */,
|
||||
85ED189B24AD425E0085DFA0 /* TextDemo.swift */,
|
||||
85ED189C24AD425E0085DFA0 /* ForEachDemo.swift */,
|
||||
85ED189D24AD425E0085DFA0 /* TokamakDemo.swift */,
|
||||
85ED189E24AD425E0085DFA0 /* Counter.swift */,
|
||||
85ED189F24AD425E0085DFA0 /* TextFieldDemo.swift */,
|
||||
85CBD5DE24B3BF090066468A /* ToggleDemo.swift */,
|
||||
85ED18A024AD425E0085DFA0 /* EnvironmentDemo.swift */,
|
||||
B51F214F24B920B400CF2583 /* PathDemo.swift */,
|
||||
B56F22DF24BC89FD001738DF /* ColorDemo.swift */,
|
||||
B56F22E224BD1C26001738DF /* GridDemo.swift */,
|
||||
85ED189D24AD425E0085DFA0 /* TokamakDemo.swift */,
|
||||
);
|
||||
name = TokamakDemo;
|
||||
path = ../Sources/TokamakDemo;
|
||||
|
@ -328,6 +332,7 @@
|
|||
D1EE7EA724C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
||||
85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
|
||||
B5C76E4A24C73ED5003EABB2 /* AppStorageDemo.swift in Sources */,
|
||||
3DCDE44424CA6AD400910F17 /* SidebarDemo.swift in Sources */,
|
||||
85ED18AD24AD425E0085DFA0 /* TextFieldDemo.swift in Sources */,
|
||||
85ED18A724AD425E0085DFA0 /* ForEachDemo.swift in Sources */,
|
||||
854A1A9124B3E3630027BC32 /* ToggleDemo.swift in Sources */,
|
||||
|
@ -351,6 +356,7 @@
|
|||
D1EE7EA824C0DD2100C0D127 /* PickerDemo.swift in Sources */,
|
||||
85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */,
|
||||
B5C76E4B24C73ED5003EABB2 /* AppStorageDemo.swift in Sources */,
|
||||
3DCDE44524CA6AD400910F17 /* SidebarDemo.swift in Sources */,
|
||||
85ED18AC24AD425E0085DFA0 /* Counter.swift in Sources */,
|
||||
85ED18A824AD425E0085DFA0 /* ForEachDemo.swift in Sources */,
|
||||
854A1A9324B3F28F0027BC32 /* ToggleDemo.swift in Sources */,
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
// Created by Carson Katri on 7/5/20.
|
||||
//
|
||||
|
||||
public protocol ListStyle {}
|
||||
public protocol ListStyle {
|
||||
var hasDividers: Bool { get }
|
||||
}
|
||||
|
||||
/// A protocol implemented on the renderer to create platform-specific list styles.
|
||||
public protocol ListStyleDeferredToRenderer {
|
||||
func listBody<ListBody>(_ content: ListBody) -> AnyView where ListBody: View
|
||||
|
@ -51,18 +54,27 @@ public extension ListStyleDeferredToRenderer {
|
|||
public typealias DefaultListStyle = PlainListStyle
|
||||
|
||||
public struct PlainListStyle: ListStyle {
|
||||
public var hasDividers = true
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public struct GroupedListStyle: ListStyle {
|
||||
public var hasDividers = true
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public struct InsetListStyle: ListStyle {
|
||||
public var hasDividers = true
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public struct InsetGroupedListStyle: ListStyle {
|
||||
public var hasDividers = true
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public struct SidebarListStyle: ListStyle {
|
||||
public var hasDividers = false
|
||||
public init() {}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public struct _ListRow {
|
|||
public static func listRow<V: View>(_ view: V, _ style: ListStyle, isLast: Bool) -> some View {
|
||||
(style as? ListStyleDeferredToRenderer)?.listRow(view) ??
|
||||
AnyView(view.padding([.trailing, .top, .bottom]))
|
||||
if !isLast {
|
||||
if !isLast && style.hasDividers {
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public typealias PlainListStyle = TokamakCore.PlainListStyle
|
|||
public typealias InsetListStyle = TokamakCore.InsetListStyle
|
||||
public typealias GroupedListStyle = TokamakCore.GroupedListStyle
|
||||
public typealias InsetGroupedListStyle = TokamakCore.InsetGroupedListStyle
|
||||
public typealias SidebarListStyle = TokamakCore.SidebarListStyle
|
||||
|
||||
public typealias DefaultPickerStyle = TokamakCore.DefaultPickerStyle
|
||||
public typealias PopUpButtonPickerStyle = TokamakCore.PopUpButtonPickerStyle
|
||||
|
|
|
@ -88,3 +88,13 @@ extension InsetGroupedListStyle: ListStyleDeferredToRenderer {
|
|||
.padding(.leading, 20))
|
||||
}
|
||||
}
|
||||
|
||||
extension SidebarListStyle: ListStyleDeferredToRenderer {
|
||||
public func listBody<ListBody>(_ content: ListBody) -> AnyView where ListBody: View {
|
||||
AnyView(content
|
||||
.padding(.all)
|
||||
.padding(.leading, 20)
|
||||
.background(Color(0xF2F2F7))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@ struct AppStorageButtons: View {
|
|||
@SceneStorage("count") var sceneCount: Int = 0
|
||||
|
||||
var body: some View {
|
||||
Button("Increment AppStorage") { count += 1 }
|
||||
Button("Increment SceneStorage") { sceneCount += 1 }
|
||||
HStack {
|
||||
Button("Increment AppStorage") { count += 1 }
|
||||
Button("Increment SceneStorage") { sceneCount += 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2019-2020 Tokamak contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Created by Gene Z. Ragan on 7/23/20.
|
||||
//
|
||||
|
||||
import TokamakShim
|
||||
|
||||
public struct SidebarListDemo: View {
|
||||
public var body: some View {
|
||||
List {
|
||||
ForEach(0..<10) {
|
||||
Text("Item \($0 + 1)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,6 +63,14 @@ var listDemo: AnyView {
|
|||
var listDemo = ListDemo()
|
||||
#endif
|
||||
|
||||
var sidebarDemo: NavItem {
|
||||
if #available(iOS 14.0, *) {
|
||||
return NavItem("Sidebar", destination: SidebarListDemo().listStyle(SidebarListStyle()))
|
||||
} else {
|
||||
return NavItem(unavailable: "Sidebar")
|
||||
}
|
||||
}
|
||||
|
||||
var gridDemo: NavItem {
|
||||
if #available(OSX 10.16, iOS 14.0, *) {
|
||||
return NavItem("Grid", destination: GridDemo())
|
||||
|
@ -101,6 +109,7 @@ var links: [NavItem] {
|
|||
NavItem("Environment", destination: EnvironmentDemo().font(.system(size: 8))),
|
||||
NavItem("Picker", destination: PickerDemo()),
|
||||
NavItem("List", destination: listDemo),
|
||||
sidebarDemo,
|
||||
outlineGroupDemo,
|
||||
NavItem("Color", destination: ColorDemo()),
|
||||
appStorageDemo,
|
||||
|
@ -122,6 +131,8 @@ struct TokamakDemoView: View {
|
|||
} else {
|
||||
#if os(WASI)
|
||||
Text(link.id)
|
||||
#elseif os(macOS)
|
||||
Text(link.id).opacity(0.5)
|
||||
#else
|
||||
HStack {
|
||||
Text(link.id)
|
||||
|
@ -134,15 +145,11 @@ struct TokamakDemoView: View {
|
|||
.frame(minHeight: 300),
|
||||
title: "Demos"
|
||||
)
|
||||
#if os(WASI)
|
||||
return AnyView(list)
|
||||
#else
|
||||
if #available(iOS 14.0, *) {
|
||||
return AnyView(list.listStyle(SidebarListStyle()))
|
||||
} else {
|
||||
return AnyView(list)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
.environmentObject(TestEnvironment())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue