Files
letro-ios/compound-ios/Sources/Compound/Layout/ScaledFrameModifier.swift

57 lines
2.1 KiB
Swift

//
// Copyright 2023, 2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import SwiftUI
public extension View {
/// Positions this view within an invisible frame with a square size that scales relative to the user's selected font size.
func scaledFrame(size: CGFloat, alignment: Alignment = .center, relativeTo textStyle: Font.TextStyle = .body) -> some View {
scaledFrame(width: size, height: size, alignment: alignment, relativeTo: textStyle)
}
/// Positions this view within an invisible frame with a size that scales relative to the user's selected font size.
func scaledFrame(width: CGFloat, height: CGFloat, alignment: Alignment = .center, relativeTo textStyle: Font.TextStyle = .body) -> some View {
modifier(ScaledFrameModifier(width: width, height: height, alignment: alignment, relativeTo: textStyle))
}
}
private struct ScaledFrameModifier: ViewModifier {
@ScaledMetric var width: CGFloat
@ScaledMetric var height: CGFloat
let alignment: Alignment
init(width: CGFloat, height: CGFloat, alignment: Alignment, relativeTo textStyle: Font.TextStyle) {
_width = ScaledMetric(wrappedValue: width, relativeTo: textStyle)
_height = ScaledMetric(wrappedValue: height, relativeTo: textStyle)
self.alignment = alignment
}
func body(content: Content) -> some View {
content.frame(width: width, height: height, alignment: alignment)
}
}
// MARK: - Previews
struct ScaledFrameModifier_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
VStack {
ForEach(DynamicTypeSize.allCases, id: \.self) { size in
likeButtonLabel
.dynamicTypeSize(size)
}
}
}
static var likeButtonLabel: some View {
Image(systemSymbol: .heartCircleFill)
.resizable()
.foregroundStyle(.compound.iconAccentTertiary)
.scaledFrame(size: 24, relativeTo: .title)
}
}