diff --git a/.changeset/busy-seals-relax.md b/.changeset/busy-seals-relax.md new file mode 100644 index 00000000..d1c5630c --- /dev/null +++ b/.changeset/busy-seals-relax.md @@ -0,0 +1,5 @@ +--- +'react-native-bottom-tabs': patch +--- + +fix: make sure everything works correctly on macOS diff --git a/packages/react-native-bottom-tabs/ios/TabBarFontSize.swift b/packages/react-native-bottom-tabs/ios/TabBarFontSize.swift index 48d93575..dec5c0ae 100644 --- a/packages/react-native-bottom-tabs/ios/TabBarFontSize.swift +++ b/packages/react-native-bottom-tabs/ios/TabBarFontSize.swift @@ -1,10 +1,16 @@ import React +#if os(macOS) +import AppKit +#else import UIKit +#endif enum TabBarFontSize { /// Returns the default font size for tab bar item labels based on the current platform #if os(tvOS) static let defaultSize: CGFloat = 30.0 +#elseif os(macOS) + static let defaultSize: CGFloat = 11.0 #else static let defaultSize: CGFloat = { if UIDevice.current.userInterfaceIdiom == .pad { diff --git a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift index dccb41b2..72938be9 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift @@ -20,7 +20,9 @@ struct TabViewImpl: View { onLayout: onLayout, onSelect: onSelect ) { + #if !os(macOS) updateTabBarAppearance(props: props, tabBar: tabBar) + #endif } } else { LegacyTabView( @@ -28,7 +30,9 @@ struct TabViewImpl: View { onLayout: onLayout, onSelect: onSelect ) { + #if !os(macOS) updateTabBarAppearance(props: props, tabBar: tabBar) + #endif } } } @@ -57,8 +61,10 @@ struct TabViewImpl: View { } #endif .introspectTabView { tabController in +#if !os(macOS) tabController.view.backgroundColor = .clear tabController.viewControllers?.forEach { $0.view.backgroundColor = .clear } +#endif #if os(macOS) tabBar = tabController #else @@ -276,7 +282,7 @@ extension View { @ViewBuilder func tabBarMinimizeBehavior(_ behavior: MinimizeBehavior?) -> some View { #if compiler(>=6.2) - if #available(iOS 26.0, *) { + if #available(iOS 26.0, macOS 26.0, *) { if let behavior { self.tabBarMinimizeBehavior(behavior.convert()) } else { diff --git a/packages/react-native-bottom-tabs/ios/TabViewProps.swift b/packages/react-native-bottom-tabs/ios/TabViewProps.swift index 5b65f0b4..cd098c07 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewProps.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewProps.swift @@ -7,8 +7,11 @@ internal enum MinimizeBehavior: String { case onScrollDown #if compiler(>=6.2) - @available(iOS 26.0, *) + @available(iOS 26.0, macOS 26.0, *) func convert() -> TabBarMinimizeBehavior { +#if os(macOS) + return .automatic +#else switch self { case .automatic: return .automatic @@ -19,6 +22,7 @@ internal enum MinimizeBehavior: String { case .onScrollDown: return .onScrollDown } +#endif } #endif } diff --git a/packages/react-native-bottom-tabs/ios/TabViewProvider.swift b/packages/react-native-bottom-tabs/ios/TabViewProvider.swift index 934b8163..013032f0 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewProvider.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewProvider.swift @@ -165,7 +165,7 @@ public final class TabInfo: NSObject { self.init() self.delegate = delegate } - + @objc public func setImageLoader(_ imageLoader: RCTImageLoader) { self.imageLoader = imageLoader loadIcons(icons) @@ -204,7 +204,9 @@ public final class TabInfo: NSObject { if let hostingController = self.hostingController, let parentViewController = reactViewController() { parentViewController.addChild(hostingController) +#if !os(macOS) hostingController.view.backgroundColor = .clear +#endif addSubview(hostingController.view) hostingController.view.translatesAutoresizingMaskIntoConstraints = false hostingController.view.pinEdges(to: self) @@ -215,7 +217,7 @@ public final class TabInfo: NSObject { } @objc(insertChild:atIndex:) - public func insertChild(_ child: UIView, at index: Int) { + public func insertChild(_ child: PlatformView, at index: Int) { guard index >= 0 && index <= props.children.count else { return } @@ -232,7 +234,7 @@ public final class TabInfo: NSObject { private func loadIcons(_ icons: NSArray?) { guard let imageLoader else { return } - + // TODO: Diff the arrays and update only changed items. // Now if the user passes `unfocusedIcon` we update every item. if let imageSources = icons as? [RCTImageSource?] { @@ -244,7 +246,7 @@ public final class TabInfo: NSObject { scale: imageSource.scale, clipped: true, resizeMode: RCTResizeMode.contain, - progressBlock: { _,_ in }, + progressBlock: { _, _ in }, partialLoad: { _ in }, completionBlock: { error, image in if error != nil { @@ -254,7 +256,7 @@ public final class TabInfo: NSObject { guard let image else { return } DispatchQueue.main.async { [weak self] in guard let self else { return } - self.props.icons[index] = image.resizeImageTo(size: self.iconSize) + props.icons[index] = image.resizeImageTo(size: iconSize) } }) }