diff --git a/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj b/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj index 5742008b..b2c12237 100644 --- a/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj +++ b/NativeDemo/TokamakDemo.xcodeproj/project.pbxproj @@ -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 = ""; }; 85CBD5DE24B3BF090066468A /* ToggleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleDemo.swift; sourceTree = ""; }; 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 */, diff --git a/Sources/TokamakCore/Styles/ListStyle.swift b/Sources/TokamakCore/Styles/ListStyle.swift index 1ba02bec..61e49bc6 100644 --- a/Sources/TokamakCore/Styles/ListStyle.swift +++ b/Sources/TokamakCore/Styles/ListStyle.swift @@ -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(_ 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() {} } diff --git a/Sources/TokamakCore/Views/Containers/List.swift b/Sources/TokamakCore/Views/Containers/List.swift index 8e9af4fb..5f56fee9 100644 --- a/Sources/TokamakCore/Views/Containers/List.swift +++ b/Sources/TokamakCore/Views/Containers/List.swift @@ -120,7 +120,7 @@ public struct _ListRow { public static func listRow(_ 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() } } diff --git a/Sources/TokamakDOM/Core.swift b/Sources/TokamakDOM/Core.swift index 959beec2..931b8ed2 100644 --- a/Sources/TokamakDOM/Core.swift +++ b/Sources/TokamakDOM/Core.swift @@ -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 diff --git a/Sources/TokamakDOM/Views/Containers/List.swift b/Sources/TokamakDOM/Views/Containers/List.swift index 7556672a..716b15ef 100644 --- a/Sources/TokamakDOM/Views/Containers/List.swift +++ b/Sources/TokamakDOM/Views/Containers/List.swift @@ -88,3 +88,13 @@ extension InsetGroupedListStyle: ListStyleDeferredToRenderer { .padding(.leading, 20)) } } + +extension SidebarListStyle: ListStyleDeferredToRenderer { + public func listBody(_ content: ListBody) -> AnyView where ListBody: View { + AnyView(content + .padding(.all) + .padding(.leading, 20) + .background(Color(0xF2F2F7)) + ) + } +} diff --git a/Sources/TokamakDemo/AppStorageDemo.swift b/Sources/TokamakDemo/AppStorageDemo.swift index 25e5aec2..cb37111c 100644 --- a/Sources/TokamakDemo/AppStorageDemo.swift +++ b/Sources/TokamakDemo/AppStorageDemo.swift @@ -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 } + } } } diff --git a/Sources/TokamakDemo/SidebarDemo.swift b/Sources/TokamakDemo/SidebarDemo.swift new file mode 100644 index 00000000..12ac6ee2 --- /dev/null +++ b/Sources/TokamakDemo/SidebarDemo.swift @@ -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)") + } + } + } +} diff --git a/Sources/TokamakDemo/TokamakDemo.swift b/Sources/TokamakDemo/TokamakDemo.swift index 0f7e7475..67924618 100644 --- a/Sources/TokamakDemo/TokamakDemo.swift +++ b/Sources/TokamakDemo/TokamakDemo.swift @@ -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()) }