DEV Community

Edvinas Bartkus
Edvinas Bartkus

Posted on

Translucent Sidebar with React Native for MacOS

Since there was news about React Native for MacOS being supported by Microsoft engineers I was excited to try it out. When thinking of a potential MacOS app there is one common pattern to have Sidebar in your main window.

The Sidebar is well documented in Human Interface Guidelines. Usually, it has a semi-transparent background slightly blurred. More accurately, it's a translucent window.

Alt Text

I was interested, is it possible to get this effect in React Native. Half an hour later, I got it working, and here are my notes on how to achieve it.

Key thing is that the effect is part of Cocoa API. There is no problem to use it for React Native MacOS. Simply include #import <Cocoa/Cocoa.h> and you can use NSVisualEffectView that will get you this effect.

NSVisualEffectView can be simply a block that can be placed anywhere and you can add child views inside of it. Following Native Modules guidelines it's very straightforward.

SidebarView.h

#import <Cocoa/Cocoa.h>

@interface SidebarView : NSView
@end
Enter fullscreen mode Exit fullscreen mode

SidebarView.m

#import "SidebarView.h"

@implementation SidebarView

- (instancetype)initWithFrame:(NSRect)frame
{
  if (NSClassFromString(@"NSVisualEffectView")) {
    self = [[NSClassFromString(@"NSVisualEffectView") alloc] initWithFrame:frame];
  } else {
    self = [super initWithFrame:frame];
  }

  return self;
}

@end
Enter fullscreen mode Exit fullscreen mode

SidebarViewManager.h

#import <React/RCTViewManager.h>

@interface SidebarViewManager : RCTViewManager
@end
Enter fullscreen mode Exit fullscreen mode

SidebarViewManager.m

#import "SidebarViewManager.h"
#import "SidebarView.h"
#import <React/RCTBridge.h>

@implementation SidebarViewManager

RCT_EXPORT_MODULE();

@synthesize bridge = _bridge;

- (NSView *)view
{
  return [[SidebarView alloc] init];
}

@end
Enter fullscreen mode Exit fullscreen mode

On JavaScript side:

SidebarView.macos.js

import {requireNativeComponent} from 'react-native';

const SidebarBackgroundView = requireNativeComponent('SidebarView');

export default SidebarBackgroundView;
Enter fullscreen mode Exit fullscreen mode

App.js

import React from 'react';
import {StyleSheet, View} from 'react-native';
import SidebarView from './SidebarView';

const App = () => {
  return (
    <View style={styles.container}>
      <SidebarView style={styles.sidebar} />
      <View style={styles.main} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  sidebar: {
    flex: 1,
  },
  main: {
    flex: 2,
  },
});

export default App;
Enter fullscreen mode Exit fullscreen mode

And here is the result:
Alt Text

Full code example: https://github.com/edvinasbartkus/react-native-macos-translucent-sidebar

If you need any help, reach me at @edvinasbartkus

Top comments (1)

Collapse
 
konradkpl profile image
Konrad Kruk

Great article! I followed your tutorial and managed to add Translucent Sidebar. As total React Native newbie and first-time XCode user it wasn't obvious to me that I need to add those files to the project (creating them on filesystem wasn't enought).

I did it just out of curiosity, without intending to use it in my current project. Dark-mode broke my layout and had problems with TouchableHighlight clicks, so I reverted the change to focus more important problems, but it's good to know there are such possibilities and can't wait to see more native components for macOS.