Skip to content

Commit

Permalink
feat: add support for top border color on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Nodonisko committed Dec 4, 2024
1 parent eda6b67 commit 9612726
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions apps/example/src/Examples/TintColors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default function TintColorsExample() {
tabBarActiveTintColor="red"
tabBarInactiveTintColor="orange"
scrollEdgeAppearance="default"
borderColor="red"
/>
);
}
5 changes: 5 additions & 0 deletions docs/docs/docs/guides/standalone-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ Whether the tab bar is translucent.
Color of tab indicator.
- Type: `ColorValue`

#### `borderColor` <Badge text="iOS" type="info" />

Color of the tab bar top border.
- Type: `ColorValue`

### Route Configuration

Each route in the `routes` array can have the following properties:
Expand Down
5 changes: 5 additions & 0 deletions docs/docs/docs/guides/usage-with-react-navigation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ Available options:
It's recommended to use `transparent` or `opaque` without lazy loading as the tab bar background flashes when a view is rendered lazily.
:::

#### `borderColor` <Badge text="iOS" type="info" />

Color of the tab bar top border.
- Type: `ColorValue`

#### `sidebarAdaptable` <Badge text="iOS" type="info" />

A tab bar style that adapts to each platform.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
_tabViewProvider.inactiveTintColor = RCTUIColorFromSharedColor(newViewProps.inactiveTintColor);
}

if (oldViewProps.borderColor != newViewProps.borderColor) {
_tabViewProvider.borderColor = RCTUIColorFromSharedColor(newViewProps.borderColor);
}

if (oldViewProps.hapticFeedbackEnabled != newViewProps.hapticFeedbackEnabled) {
_tabViewProvider.hapticFeedbackEnabled = newViewProps.hapticFeedbackEnabled;
}

if (oldViewProps.fontSize != newViewProps.fontSize) {
_tabViewProvider.fontSize = [NSNumber numberWithInt:newViewProps.fontSize];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ @implementation RCTTabView
RCT_EXPORT_VIEW_PROPERTY(barTintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(activeTintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(inactiveTintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(borderColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(hapticFeedbackEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(fontFamily, NSString)
RCT_EXPORT_VIEW_PROPERTY(fontWeight, NSString)
Expand Down
13 changes: 13 additions & 0 deletions packages/react-native-bottom-tabs/ios/TabViewImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class TabViewProps: ObservableObject {
@Published var ignoresTopSafeArea: Bool = true
@Published var disablePageAnimations: Bool = false
@Published var hapticFeedbackEnabled: Bool = false
@Published var borderColor: UIColor?
@Published var fontSize: Int?
@Published var fontFamily: String?
@Published var fontWeight: String?
Expand Down Expand Up @@ -241,6 +242,11 @@ private func configureTransparentAppearance(tabBar: UITabBar, props: TabViewProp
items.forEach { item in
item.setTitleTextAttributes(attributes, for: .normal)
}

if let borderColor = props.borderColor {
tabBar.layer.borderWidth = 0.5
tabBar.layer.borderColor = borderColor.cgColor
}
}

private func configureStandardAppearance(tabBar: UITabBar, props: TabViewProps) {
Expand Down Expand Up @@ -281,6 +287,10 @@ private func configureStandardAppearance(tabBar: UITabBar, props: TabViewProps)
appearance.inlineLayoutAppearance = itemAppearance
appearance.compactInlineLayoutAppearance = itemAppearance

if let borderColor = props.borderColor {
appearance.shadowColor = borderColor
}

// Apply final appearance
tabBar.standardAppearance = appearance
if #available(iOS 15.0, *) {
Expand Down Expand Up @@ -364,6 +374,9 @@ extension View {
.onChange(of: props.fontWeight) { newValue in
updateTabBarAppearance(props: props, tabBar: tabBar)
}
.onChange(of: props.borderColor) { newValue in
updateTabBarAppearance(props: props, tabBar: tabBar)
}
}

@ViewBuilder
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native-bottom-tabs/ios/TabViewProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ public final class TabInfo: NSObject {
}
}

@objc public var borderColor: UIColor? {
didSet {
props.borderColor = borderColor
}
}

@objc public var fontFamily: NSString? {
didSet {
props.fontFamily = fontFamily as? String
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-bottom-tabs/src/TabView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ interface Props<Route extends BaseRoute> {
* Describes the appearance attributes for the tabBar to use when an observable scroll view is scrolled to the bottom. (iOS only)
*/
scrollEdgeAppearance?: 'default' | 'opaque' | 'transparent';
/**
* Color of the tab bar top border.
*/
borderColor?: ColorValue;
/**
* Active tab color.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface TabViewProps extends ViewProps {
ignoresTopSafeArea?: WithDefault<boolean, true>;
disablePageAnimations?: boolean;
activeIndicatorColor?: ColorValue;
borderColor?: ColorValue;
hapticFeedbackEnabled?: boolean;
fontFamily?: string;
fontWeight?: string;
Expand Down

0 comments on commit 9612726

Please sign in to comment.