Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTML implementation for opacity modifier #415

Merged
merged 15 commits into from
Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions NativeDemo/TokamakDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
B5F2BE042571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */; };
D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */; };
D120FDDC257E7145008FFBAD /* TextEditorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */; };
D1316F202500352200224A67 /* StackDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1316F1F2500352200224A67 /* StackDemo.swift */; };
D1316F212500352200224A67 /* StackDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1316F1F2500352200224A67 /* StackDemo.swift */; };
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */; };
Expand Down Expand Up @@ -122,6 +124,7 @@
B5DBA22A24D509B4003D3347 /* RedactDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedactDemo.swift; sourceTree = "<group>"; };
B5F2BE022571443D00FB3653 /* PreferenceKeyDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceKeyDemo.swift; sourceTree = "<group>"; };
D120FDDA257E7145008FFBAD /* TextEditorDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEditorDemo.swift; sourceTree = "<group>"; };
D1316F1F2500352200224A67 /* StackDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackDemo.swift; sourceTree = "<group>"; };
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListDemo.swift; sourceTree = "<group>"; };
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutlineGroupDemo.swift; sourceTree = "<group>"; };
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonStyleDemo.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -192,11 +195,13 @@
D1D6B62224D817350041E1D9 /* GeometryReaderDemo.swift */,
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */,
B5C76E4924C73ED4003EABB2 /* AppStorageDemo.swift */,
D1C726F224CB63C6003B576D /* ButtonStyleDemo.swift */,
B56F22DF24BC89FD001738DF /* ColorDemo.swift */,
85ED189E24AD425E0085DFA0 /* Counter.swift */,
207C056F2610E16E00BBBE54 /* DatePickerDemo.swift */,
85ED18A024AD425E0085DFA0 /* EnvironmentDemo.swift */,
85ED189C24AD425E0085DFA0 /* ForEachDemo.swift */,
D1D6B62224D817350041E1D9 /* GeometryReaderDemo.swift */,
B56F22E224BD1C26001738DF /* GridDemo.swift */,
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */,
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */,
Expand All @@ -207,6 +212,7 @@
3DCDE44324CA6AD400910F17 /* SidebarDemo.swift */,
8500293E24D2FF3E001A2E84 /* SliderDemo.swift */,
85ED189A24AD425E0085DFA0 /* SpacerDemo.swift */,
D1316F1F2500352200224A67 /* StackDemo.swift */,
85ED189B24AD425E0085DFA0 /* TextDemo.swift */,
85ED189F24AD425E0085DFA0 /* TextFieldDemo.swift */,
85CBD5DE24B3BF090066468A /* ToggleDemo.swift */,
Expand Down Expand Up @@ -369,6 +375,7 @@
D1EE7EA724C0DD2100C0D127 /* PickerDemo.swift in Sources */,
D120FDDB257E7145008FFBAD /* TextEditorDemo.swift in Sources */,
B5F2BE032571443D00FB3653 /* PreferenceKeyDemo.swift in Sources */,
D1316F202500352200224A67 /* StackDemo.swift in Sources */,
8500293F24D2FF3E001A2E84 /* SliderDemo.swift in Sources */,
4550BD5225B642B80088F4EA /* ShadowDemo.swift in Sources */,
85ED18A924AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
Expand All @@ -389,6 +396,7 @@
files = (
85ED18AA24AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
207C05712610E16E00BBBE54 /* DatePickerDemo.swift in Sources */,
D1316F212500352200224A67 /* StackDemo.swift in Sources */,
B56F22E424BD1C26001738DF /* GridDemo.swift in Sources */,
D1B4229324B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */,
D1D6B62424D817350041E1D9 /* GeometryReaderDemo.swift in Sources */,
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ app.
Any browser that [supports WebAssembly](https://caniuse.com/#feat=wasm) should work, which currently includes:

- Edge 16+
- Firefox 53+
- Chrome 57+
- (Mobile) Safari 11+
- Firefox 61+
- Chrome 66+
- (Mobile) Safari 12+

Not all of these were tested though, compatibility reports are very welcome!

Expand Down
34 changes: 34 additions & 0 deletions Sources/TokamakCore/Modifiers/Effects/OpacityEffect.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2021 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 Carson Katri on 1/20/21.
//

public struct _OpacityEffect: ViewModifier, Equatable {
public let opacity: Double

public init(opacity: Double) {
self.opacity = opacity
}

public func body(content: Content) -> some View {
content
}
}

public extension View {
func opacity(_ opacity: Double) -> some View {
modifier(_OpacityEffect(opacity: opacity))
}
}
2 changes: 1 addition & 1 deletion Sources/TokamakCore/Stubs/CGStubs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
// Created by Max Desiatov on 08/04/2020.
//

import Foundation
import CoreFoundation
import Foundation

extension CGPoint {
func rotate(_ angle: Angle, around origin: Self) -> Self {
Expand Down
4 changes: 2 additions & 2 deletions Sources/TokamakCore/Views/Containers/List/List.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public struct List<SelectionValue, Content>: View
}

var listStack: some View {
VStack(alignment: .leading) { () -> AnyView in
VStack(alignment: .leading, spacing: 0) { () -> AnyView in
if let contentContainer = content as? ParentView {
var sections = [AnyView]()
var currentSection = [AnyView]()
Expand Down Expand Up @@ -103,7 +103,7 @@ public enum _ListRow {
@ViewBuilder rowView: @escaping (AnyView, Bool) -> RowView
) -> some View where RowView: View {
ForEach(Array(children.enumerated()), id: \.offset) { offset, view in
VStack(alignment: .leading) {
VStack(alignment: .leading, spacing: 0) {
HStack { Spacer() }
rowView(view, offset == children.count - 1)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/TokamakCore/Views/Containers/Section.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ extension Section: View, SectionView where Parent: View, Content: View, Footer:

func listRow(_ style: ListStyle) -> AnyView {
AnyView(
VStack(alignment: .leading) {
VStack(alignment: .leading, spacing: 0) {
headerView(style)
sectionContent(style)
footerView(style)
Expand Down
14 changes: 12 additions & 2 deletions Sources/TokamakCore/Views/Layout/HStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public enum VerticalAlignment: Equatable {
case bottom
}

public let defaultStackSpacing: CGFloat = 8

/// A view that arranges its children in a horizontal line.
///
/// HStack {
Expand All @@ -32,7 +34,7 @@ public enum VerticalAlignment: Equatable {
/// }
public struct HStack<Content>: _PrimitiveView where Content: View {
public let alignment: VerticalAlignment
public let spacing: CGFloat?
let spacing: CGFloat
public let content: Content

public init(
Expand All @@ -41,7 +43,7 @@ public struct HStack<Content>: _PrimitiveView where Content: View {
@ViewBuilder content: () -> Content
) {
self.alignment = alignment
self.spacing = spacing
self.spacing = spacing ?? defaultStackSpacing
self.content = content()
}
}
Expand All @@ -52,3 +54,11 @@ extension HStack: ParentView {
(content as? GroupView)?.children ?? [AnyView(content)]
}
}

public struct _HStackProxy<Content> where Content: View {
public let subject: HStack<Content>

public init(_ subject: HStack<Content>) { self.subject = subject }

public var spacing: CGFloat { subject.spacing }
}
12 changes: 10 additions & 2 deletions Sources/TokamakCore/Views/Layout/VStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public enum HorizontalAlignment: Equatable {
/// }
public struct VStack<Content>: _PrimitiveView where Content: View {
public let alignment: HorizontalAlignment
public let spacing: CGFloat?
let spacing: CGFloat
public let content: Content

public init(
Expand All @@ -38,7 +38,7 @@ public struct VStack<Content>: _PrimitiveView where Content: View {
@ViewBuilder content: () -> Content
) {
self.alignment = alignment
self.spacing = spacing
self.spacing = spacing ?? defaultStackSpacing
self.content = content()
}
}
Expand All @@ -49,3 +49,11 @@ extension VStack: ParentView {
(content as? GroupView)?.children ?? [AnyView(content)]
}
}

public struct _VStackProxy<Content> where Content: View {
public let subject: VStack<Content>

public init(_ subject: VStack<Content>) { self.subject = subject }

public var spacing: CGFloat { subject.spacing }
}
40 changes: 40 additions & 0 deletions Sources/TokamakDemo/StackDemo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 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.

import Foundation
import TokamakShim

struct StackDemo: View {
@State private var horizontalSpacing: CGFloat = 8
@State private var verticalSpacing: CGFloat = 8

var body: some View {
VStack(spacing: verticalSpacing) {
Text("Horizontal Spacing")
Slider(value: $horizontalSpacing, in: 0...100)

Text("Vertical Spacing")
Slider(value: $verticalSpacing, in: 0...100)
HStack(spacing: horizontalSpacing) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 100)

Rectangle()
.fill(Color.green)
.frame(width: 100, height: 100)
}
}
}
}
1 change: 1 addition & 0 deletions Sources/TokamakDemo/TokamakDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct TokamakDemoView: View {
}
}
Section(header: Text("Layout")) {
NavItem("HStack/VStack", destination: StackDemo())
if #available(OSX 10.16, iOS 14.0, *) {
NavItem("Grid", destination: GridDemo())
} else {
Expand Down
4 changes: 2 additions & 2 deletions Sources/TokamakGTK/Views/Stack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extension VStack: GTKPrimitive {
Box(
content: content,
orientation: GTK_ORIENTATION_VERTICAL,
spacing: spacing ?? 8,
spacing: _VStackProxy(self).spacing,
alignment: .init(horizontal: alignment, vertical: .center)
)
)
Expand All @@ -73,7 +73,7 @@ extension HStack: GTKPrimitive {
Box(
content: content,
orientation: GTK_ORIENTATION_HORIZONTAL,
spacing: spacing ?? 8,
spacing: _HStackProxy(self).spacing,
alignment: .init(horizontal: .center, vertical: alignment)
)
)
Expand Down
24 changes: 24 additions & 0 deletions Sources/TokamakStaticHTML/Modifiers/Effects/OpacityEffect.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2021 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 Carson Katri on 1/20/21.
//

import TokamakCore

extension _OpacityEffect: DOMViewModifier {
public var attributes: [HTMLAttribute: String] {
["style": "opacity: \(opacity)"]
MaxDesiatov marked this conversation as resolved.
Show resolved Hide resolved
}
}
14 changes: 12 additions & 2 deletions Sources/TokamakStaticHTML/Resources/TokamakStyles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import TokamakCore

public let tokamakStyles = """
._tokamak-stack > * {
flex-shrink: 0;
._tokamak-stack {
display: grid;
}
._tokamak-hstack {
grid-auto-flow: column;
column-gap: var(--tokamak-stack-gap, \(Int(defaultStackSpacing))px);
}
._tokamak-vstack {
grid-auto-flow: row;
row-gap: var(--tokamak-stack-gap, \(Int(defaultStackSpacing))px);
}
._tokamak-scrollview-hideindicators {
scrollbar-color: transparent;
Expand Down
9 changes: 6 additions & 3 deletions Sources/TokamakStaticHTML/Views/Layout/HStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ extension HStack: _HTMLPrimitive, SpacerContainer {

@_spi(TokamakStaticHTML)
public var renderedBody: AnyView {
AnyView(HTML("div", [
let spacing = _HStackProxy(self).spacing

return AnyView(HTML("div", [
"style": """
display: flex; flex-direction: row; align-items: \(alignment.cssValue);
align-items: \(alignment.cssValue);
\(hasSpacer ? "width: 100%;" : "")
\(fillCrossAxis ? "height: 100%;" : "")
\(spacing != defaultStackSpacing ? "--tokamak-stack-gap: \(spacing)px" : "")
""",
"class": "_tokamak-stack",
"class": "_tokamak-stack _tokamak-hstack",
]) { content })
}
}
9 changes: 6 additions & 3 deletions Sources/TokamakStaticHTML/Views/Layout/VStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ extension VStack: _HTMLPrimitive, SpacerContainer {

@_spi(TokamakStaticHTML)
public var renderedBody: AnyView {
AnyView(HTML("div", [
let spacing = _VStackProxy(self).spacing

return AnyView(HTML("div", [
"style": """
display: flex; flex-direction: column; align-items: \(alignment.cssValue);
justify-items: \(alignment.cssValue);
\(hasSpacer ? "height: 100%;" : "")
\(fillCrossAxis ? "width: 100%;" : "")
\(spacing != defaultStackSpacing ? "--tokamak-stack-gap: \(spacing)px" : "")
""",
"class": "_tokamak-stack",
"class": "_tokamak-stack _tokamak-vstack",
]) { content })
}
}
Loading