Skip to content

Commit

Permalink
Merge pull request #744 from grahammendick/ios-bottomsheet
Browse files Browse the repository at this point in the history
  • Loading branch information
grahammendick authored Nov 10, 2023
2 parents be29d80 + c9ac65c commit a190192
Show file tree
Hide file tree
Showing 19 changed files with 706 additions and 15 deletions.
15 changes: 9 additions & 6 deletions NavigationReactNative/src/BottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class BottomSheet extends React.Component<any, any> {
}
onDetentChanged({nativeEvent}) {
var {eventCount: mostRecentEventCount, detent: nativeDetent} = nativeEvent;
var detents = (UIManager as any).getViewManagerConfig('NVBottomSheet').Constants.Detent
var detent = Object.keys(detents).find(name => detents[name] === nativeDetent)
var detents = (UIManager as any).getViewManagerConfig('NVBottomSheet').Constants?.Detent;
var detent = Platform.OS === 'android'? Object.keys(detents).find(name => detents[name] === nativeDetent) : nativeDetent;
this.dragging = !detent
if (detent) {
this.changeDetent(detent);
Expand All @@ -39,14 +39,15 @@ class BottomSheet extends React.Component<any, any> {
}
}
render() {
if (Platform.OS === 'ios') return null;
if (Platform.OS === 'ios' && +Platform.Version < 15) return null;
var { expandedHeight, expandedOffset, peekHeight, halfExpandedRatio, hideable, skipCollapsed, draggable, children } = this.props
const detents = (UIManager as any).getViewManagerConfig('NVBottomSheet').Constants.Detent
const detents = (UIManager as any).getViewManagerConfig('NVBottomSheet').Constants?.Detent;
return (
<NVBottomSheet
ref={this.ref}
detent={detents[this.state.selectedDetent]}
detent={Platform.OS === 'android' ? '' + detents[this.state.selectedDetent] : this.state.selectedDetent}
peekHeight={peekHeight}
expandedHeight={expandedHeight}
expandedOffset={expandedOffset}
fitToContents={expandedOffset == null}
halfExpandedRatio={halfExpandedRatio}
Expand All @@ -61,7 +62,9 @@ class BottomSheet extends React.Component<any, any> {
styles.bottomSheet,
expandedHeight != null ? { height: expandedHeight } : null,
expandedOffset != null ? { top: expandedOffset } : null,
expandedHeight == null && expandedOffset == null ? { top: 0 } : null
expandedHeight == null && expandedOffset == null ? { top: 0 } : null,
Platform.OS === 'ios' ? { height: undefined, top: undefined } : null,
{ display: this.state.selectedDetent !== 'hidden' ? 'flex' : 'none' },
]}
>
{children}
Expand Down
6 changes: 4 additions & 2 deletions NavigationReactNative/src/BottomSheetNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati

type NativeProps = $ReadOnly<{|
...ViewProps,
detent: Int32,
detent: string,
mostRecentEventCount: Int32,
peekHeight: Int32,
expandedHeight: Int32,
expandedOffset: Int32,
fitToContents: boolean,
halfExpandedRatio?: WithDefault<Float, -1>,
Expand All @@ -17,11 +18,12 @@ type NativeProps = $ReadOnly<{|
draggable: boolean,
sheetHeight: Double,
onDetentChanged: DirectEventHandler<$ReadOnly<{|
detent: Int32,
detent: string,
eventCount: Int32,
|}>>,
|}>;

export default (codegenNativeComponent<NativeProps>(
'NVBottomSheet',
{interfaceOnly: true}
): HostComponent<NativeProps>);
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ protected BottomSheetView createViewInstance(@NonNull ThemedReactContext reactCo
}

@ReactProp(name = "detent")
public void setDetent(BottomSheetView view, int detent) {
view.pendingDetent = detent;
public void setDetent(BottomSheetView view, String detent) {
view.pendingDetent = Integer.parseInt(detent);
}

@ReactProp(name = "mostRecentEventCount")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ protected BottomSheetView createViewInstance(@NonNull ThemedReactContext reactCo
}

@ReactProp(name = "detent")
public void setDetent(BottomSheetView view, int detent) {
view.pendingDetent = detent;
public void setDetent(BottomSheetView view, String detent) {
view.pendingDetent = Integer.parseInt(detent);
}

@ReactProp(name = "mostRecentEventCount")
Expand All @@ -57,6 +57,10 @@ public void setPeekHeight(BottomSheetView view, int peekHeight) {
view.bottomSheetBehavior.setPeekHeight((int) PixelUtil.toPixelFromDIP(peekHeight), true);
}

@Override
public void setExpandedHeight(BottomSheetView view, int value) {
}

@ReactProp(name = "expandedOffset")
public void setExpandedOffset(BottomSheetView view, int expandedOffset) {
view.bottomSheetBehavior.setExpandedOffset((int) PixelUtil.toPixelFromDIP(expandedOffset));
Expand Down
1 change: 1 addition & 0 deletions NavigationReactNative/src/cpp/navigationreactnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <jsi/jsi.h>
#include <react/renderer/components/navigationreactnative/NVActionBarComponentDescriptor.h>
#include <react/renderer/components/navigationreactnative/NVBarButtonComponentDescriptor.h>
#include <react/renderer/components/navigationreactnative/NVBottomSheetComponentDescriptor.h>
#include <react/renderer/components/navigationreactnative/NVNavigationBarComponentDescriptor.h>
#include <react/renderer/components/navigationreactnative/NVSearchBarComponentDescriptor.h>
#include <react/renderer/components/navigationreactnative/NVTabBarItemComponentDescriptor.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <react/debug/react_native_assert.h>
#include "NVBottomSheetShadowNode.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook {
namespace react {

class NVBottomSheetComponentDescriptor final
: public ConcreteComponentDescriptor<NVBottomSheetShadowNode> {
public:
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;

void adopt(ShadowNode::Unshared const &shadowNode) const override {
react_native_assert(
std::dynamic_pointer_cast<NVBottomSheetShadowNode>(shadowNode));
auto screenShadowNode =
std::static_pointer_cast<NVBottomSheetShadowNode>(shadowNode);

react_native_assert(
std::dynamic_pointer_cast<YogaLayoutableShadowNode>(screenShadowNode));
auto layoutableShadowNode =
std::static_pointer_cast<YogaLayoutableShadowNode>(screenShadowNode);

auto state =
std::static_pointer_cast<const NVBottomSheetShadowNode::ConcreteState>(
shadowNode->getState());
auto stateData = state->getData();

if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
layoutableShadowNode->setSize(
Size{stateData.frameSize.width, stateData.frameSize.height});
}

ConcreteComponentDescriptor::adopt(shadowNode);
}
};

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "NVBottomSheetShadowNode.h"

namespace facebook {
namespace react {

extern const char NVBottomSheetComponentName[] = "NVBottomSheet";

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include "NVBottomSheetState.h"
#include <react/renderer/components/navigationreactnative/EventEmitters.h>
#include <react/renderer/components/navigationreactnative/Props.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>

namespace facebook {
namespace react {

JSI_EXPORT extern const char NVBottomSheetComponentName[];

class JSI_EXPORT NVBottomSheetShadowNode final : public ConcreteViewShadowNode<
NVBottomSheetComponentName,
NVBottomSheetProps,
NVBottomSheetEventEmitter,
NVBottomSheetState> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;

static ShadowNodeTraits BaseTraits() {
auto traits = ConcreteViewShadowNode::BaseTraits();
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
return traits;
}
};

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "NVBottomSheetState.h"

namespace facebook {
namespace react {

#ifdef ANDROID
folly::dynamic NVBottomSheetState::getDynamic() const {
return folly::dynamic::object("frameWidth", frameSize.width)(
"frameHeight", frameSize.height);
}
#endif

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <react/renderer/graphics/Float.h>
#include <react/renderer/core/graphicsConversions.h>

#ifdef ANDROID
#include <folly/dynamic.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif

namespace facebook {
namespace react {

class JSI_EXPORT NVBottomSheetState final {
public:
using Shared = std::shared_ptr<const NVBottomSheetState>;

NVBottomSheetState(){};
NVBottomSheetState(Size frameSize_) : frameSize(frameSize_){};

#ifdef ANDROID
NVBottomSheetState(
NVBottomSheetState const &previousState,
folly::dynamic data)
: frameSize(Size{
(Float)data["frameWidth"].getDouble(),
(Float)data["frameHeight"].getDouble()}){};
#endif

const Size frameSize{};

#ifdef ANDROID
folly::dynamic getDynamic() const;
MapBuffer getMapBuffer() const {
return MapBufferBuilder::EMPTY();
};

#endif

#pragma mark - Getters
};

} // namespace react
} // namespace facebook
3 changes: 2 additions & 1 deletion NavigationReactNative/src/ios/NVBottomSheetComponentView.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

NS_ASSUME_NONNULL_BEGIN

@interface NVBottomSheetComponentView : RCTViewComponentView
API_AVAILABLE(ios(15.0))
@interface NVBottomSheetComponentView : RCTViewComponentView <UISheetPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate>

@end

Expand Down
Loading

0 comments on commit a190192

Please sign in to comment.