From 065d09eeb4ab9347aba3533bb38a362b80102afc Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Fri, 19 May 2023 11:26:25 +0800 Subject: [PATCH] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20Impl:=20`RNIComputableSize?= =?UTF-8?q?`=20-=20Min/Max=20Size?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/FloatingPoint+Clamping.swift | 24 +++++++ .../RNIComputable/RNIComputableSize.swift | 67 +++++++++++++++++-- .../RNIComputable/RNIComputableSizeMode.swift | 12 +++- src/types/RNIComputable/RNIComputableSize.ts | 6 ++ 4 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 ios/src_library/Extensions/FloatingPoint+Clamping.swift diff --git a/ios/src_library/Extensions/FloatingPoint+Clamping.swift b/ios/src_library/Extensions/FloatingPoint+Clamping.swift new file mode 100644 index 00000000..24907733 --- /dev/null +++ b/ios/src_library/Extensions/FloatingPoint+Clamping.swift @@ -0,0 +1,24 @@ +// +// FloatingPoint+Helpers.swift +// swift-programmatic-modal +// +// Created by Dominic Go on 5/19/23. +// + +import Foundation + +extension FloatingPoint { + public func clamped(min lowerBound: Self?, max upperBound: Self?) -> Self { + var clampedValue = self; + + if let upperBound = upperBound { + clampedValue = min(clampedValue, upperBound); + }; + + if let lowerBound = lowerBound { + clampedValue = max(clampedValue, lowerBound); + }; + + return clampedValue; + }; +}; diff --git a/ios/src_library/React Native/RNIComputable/RNIComputableSize.swift b/ios/src_library/React Native/RNIComputable/RNIComputableSize.swift index 7440639a..ebdf45dd 100644 --- a/ios/src_library/React Native/RNIComputable/RNIComputableSize.swift +++ b/ios/src_library/React Native/RNIComputable/RNIComputableSize.swift @@ -6,16 +6,27 @@ // import Foundation -import JavaScriptCore - public struct RNIComputableSize { + + // MARK: - Properties + // ------------------ + public let mode: RNIComputableSizeMode; public let offsetWidth: RNIComputableOffset?; public let offsetHeight: RNIComputableOffset?; - public func computeOffsets(withSize size: CGSize) -> CGSize { + public let minWidth: CGFloat?; + public let minHeight: CGFloat?; + + public let maxWidth: CGFloat?; + public let maxHeight: CGFloat?; + + // MARK: - Internal Functions + // -------------------------- + + func sizeWithOffsets(forSize size: CGSize) -> CGSize { let offsetWidth = self.offsetWidth?.compute(withValue: size.width); @@ -28,7 +39,23 @@ public struct RNIComputableSize { ); }; - public func compute( + func sizeWithClamp(forSize size: CGSize) -> CGSize { + return CGSize( + width: size.width.clamped( + min: self.minWidth, + max: self.maxWidth + ), + height: size.height.clamped( + min: self.minHeight, + max: self.maxHeight + ) + ); + }; + + // MARK: - Functions + // ----------------- + + public func computeRaw( withTargetSize targetSize: CGSize, currentSize: CGSize ) -> CGSize { @@ -50,16 +77,17 @@ public struct RNIComputableSize { }; }; - public func computeWithOffsets( + public func compute( withTargetSize targetSize: CGSize, currentSize: CGSize ) -> CGSize { - let computedSize = self.compute( + let rawSize = self.computeRaw( withTargetSize: targetSize, currentSize: currentSize ); - return self.computeOffsets(withSize: computedSize); + let clampedSize = self.sizeWithClamp(forSize: rawSize); + return self.sizeWithOffsets(forSize: clampedSize); }; }; @@ -85,11 +113,36 @@ extension RNIComputableSize { return offset; }(); + + self.minWidth = + Self.getDoubleValue(forDict: dict, withKey: "minWidth"); + + self.minHeight = + Self.getDoubleValue(forDict: dict, withKey: "minHeight"); + + self.maxWidth = + Self.getDoubleValue(forDict: dict, withKey: "maxWidth"); + + self.maxHeight = + Self.getDoubleValue(forDict: dict, withKey: "maxHeight"); }; public init(mode: RNIComputableSizeMode){ self.mode = mode; + self.offsetWidth = nil; self.offsetHeight = nil; + self.minWidth = nil; + self.minHeight = nil; + self.maxWidth = nil; + self.maxHeight = nil; + }; + + static private func getDoubleValue( + forDict dict: NSDictionary, + withKey key: String + ) -> CGFloat? { + guard let number = dict[key] as? NSNumber else { return nil }; + return number.doubleValue; }; }; diff --git a/ios/src_library/React Native/RNIComputable/RNIComputableSizeMode.swift b/ios/src_library/React Native/RNIComputable/RNIComputableSizeMode.swift index c9f01504..b745091e 100644 --- a/ios/src_library/React Native/RNIComputable/RNIComputableSizeMode.swift +++ b/ios/src_library/React Native/RNIComputable/RNIComputableSizeMode.swift @@ -10,8 +10,16 @@ import Foundation public enum RNIComputableSizeMode { case current; case stretch; - case constant(constantWidth: Double, constantHeight: Double); - case percent(percentWidth: Double, percentHeight: Double); + + case constant( + constantWidth: Double, + constantHeight: Double + ); + + case percent( + percentWidth: Double, + percentHeight: Double + ); }; extension RNIComputableSizeMode { diff --git a/src/types/RNIComputable/RNIComputableSize.ts b/src/types/RNIComputable/RNIComputableSize.ts index c51ce8eb..52071f8d 100644 --- a/src/types/RNIComputable/RNIComputableSize.ts +++ b/src/types/RNIComputable/RNIComputableSize.ts @@ -6,6 +6,12 @@ import type { RNIComputableOffset } from './RNIComputableOffset'; type RNIComputableSizeShared = { offsetWidth?: RNIComputableOffset; offsetHeight?: RNIComputableOffset; + + minWidth?: number; + minHeight?: number; + + maxWidth?: number; + maxHeight?: number; }; type RNIComputableSizeModeBase = {