104 lines
2.8 KiB
Swift
104 lines
2.8 KiB
Swift
// 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 TokamakCore
|
|
|
|
private extension DOMViewModifier {
|
|
func unwrapToStyle<T>(
|
|
_ key: KeyPath<Self, T?>,
|
|
property: String? = nil,
|
|
defaultValue: String = ""
|
|
) -> String {
|
|
if let val = self[keyPath: key] {
|
|
if let property = property {
|
|
return "\(property): \(val)px;"
|
|
} else {
|
|
return "\(val)px;"
|
|
}
|
|
} else {
|
|
return defaultValue
|
|
}
|
|
}
|
|
}
|
|
|
|
extension _FrameLayout: DOMViewModifier {
|
|
public var attributes: [String: String] {
|
|
["style": """
|
|
\(unwrapToStyle(\.width, property: "width"))
|
|
\(unwrapToStyle(\.height, property: "height"))
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
flex-grow: 0;
|
|
flex-shrink: 0;
|
|
"""]
|
|
}
|
|
}
|
|
|
|
extension _FlexFrameLayout: DOMViewModifier {
|
|
public var attributes: [String: String] {
|
|
["style": """
|
|
\(unwrapToStyle(\.minWidth, property: "min-width"))
|
|
width: \(unwrapToStyle(\.idealWidth, defaultValue: fillWidth ? "100%" : "auto"));
|
|
\(unwrapToStyle(\.maxWidth, property: "max-width"))
|
|
\(unwrapToStyle(\.minHeight, property: "min-height"))
|
|
height: \(unwrapToStyle(\.idealHeight, defaultValue: fillHeight ? "100%" : "auto"));
|
|
\(unwrapToStyle(\.maxHeight, property: "max-height"))
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
flex-grow: 0;
|
|
flex-shrink: 0;
|
|
"""]
|
|
}
|
|
}
|
|
|
|
private extension Edge {
|
|
var cssValue: String {
|
|
switch self {
|
|
case .top: return "top"
|
|
case .trailing: return "right"
|
|
case .bottom: return "bottom"
|
|
case .leading: return "left"
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension EdgeInsets {
|
|
func inset(for edge: Edge) -> CGFloat {
|
|
switch edge {
|
|
case .top: return top
|
|
case .trailing: return trailing
|
|
case .bottom: return bottom
|
|
case .leading: return leading
|
|
}
|
|
}
|
|
}
|
|
|
|
extension _PaddingLayout: DOMViewModifier {
|
|
public var isOrderDependent: Bool { true }
|
|
public var attributes: [String: String] {
|
|
var padding = [(String, CGFloat)]()
|
|
let insets = self.insets ?? .init(_all: 10)
|
|
for edge in Edge.allCases {
|
|
if edges.contains(.init(edge)) {
|
|
padding.append((edge.cssValue, insets.inset(for: edge)))
|
|
}
|
|
}
|
|
return ["style": padding
|
|
.map { "padding-\($0.0): \($0.1);" }
|
|
.joined(separator: " ")]
|
|
}
|
|
}
|