concentric-sheet 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/NitroConcentricSheet.podspec +31 -0
  3. package/README.md +118 -0
  4. package/ios/Bridge.h +8 -0
  5. package/ios/SheetModalController.swift +912 -0
  6. package/lib/NativeSheetModal.d.ts +10 -0
  7. package/lib/NativeSheetModal.js +243 -0
  8. package/lib/index.d.ts +3 -0
  9. package/lib/index.js +1 -0
  10. package/lib/specs/SheetModalController.nitro.d.ts +46 -0
  11. package/lib/specs/SheetModalController.nitro.js +1 -0
  12. package/nitro.json +23 -0
  13. package/nitrogen/generated/.gitattributes +1 -0
  14. package/nitrogen/generated/ios/NitroConcentricSheet+autolinking.rb +60 -0
  15. package/nitrogen/generated/ios/NitroConcentricSheet-Swift-Cxx-Bridge.cpp +33 -0
  16. package/nitrogen/generated/ios/NitroConcentricSheet-Swift-Cxx-Bridge.hpp +269 -0
  17. package/nitrogen/generated/ios/NitroConcentricSheet-Swift-Cxx-Umbrella.hpp +69 -0
  18. package/nitrogen/generated/ios/NitroConcentricSheetAutolinking.mm +33 -0
  19. package/nitrogen/generated/ios/NitroConcentricSheetAutolinking.swift +26 -0
  20. package/nitrogen/generated/ios/c++/HybridSheetModalControllerSpecSwift.cpp +11 -0
  21. package/nitrogen/generated/ios/c++/HybridSheetModalControllerSpecSwift.hpp +130 -0
  22. package/nitrogen/generated/ios/swift/HybridSheetModalControllerSpec.swift +58 -0
  23. package/nitrogen/generated/ios/swift/HybridSheetModalControllerSpec_cxx.swift +181 -0
  24. package/nitrogen/generated/ios/swift/ModalCornerConfiguration.swift +83 -0
  25. package/nitrogen/generated/ios/swift/ModalCornerConfigurationType.swift +48 -0
  26. package/nitrogen/generated/ios/swift/ModalViewBackground.swift +40 -0
  27. package/nitrogen/generated/ios/swift/PresentedModalConfig.swift +129 -0
  28. package/nitrogen/generated/ios/swift/PresentedModalDetent.swift +71 -0
  29. package/nitrogen/generated/ios/swift/SheetDetentIdentifier.swift +40 -0
  30. package/nitrogen/generated/ios/swift/SheetPresentationConfig.swift +238 -0
  31. package/nitrogen/generated/ios/swift/Variant_NullType_PresentedModalDetent.swift +18 -0
  32. package/nitrogen/generated/shared/c++/HybridSheetModalControllerSpec.cpp +24 -0
  33. package/nitrogen/generated/shared/c++/HybridSheetModalControllerSpec.hpp +71 -0
  34. package/nitrogen/generated/shared/c++/ModalCornerConfiguration.hpp +97 -0
  35. package/nitrogen/generated/shared/c++/ModalCornerConfigurationType.hpp +84 -0
  36. package/nitrogen/generated/shared/c++/ModalViewBackground.hpp +76 -0
  37. package/nitrogen/generated/shared/c++/PresentedModalConfig.hpp +115 -0
  38. package/nitrogen/generated/shared/c++/PresentedModalDetent.hpp +94 -0
  39. package/nitrogen/generated/shared/c++/SheetDetentIdentifier.hpp +76 -0
  40. package/nitrogen/generated/shared/c++/SheetPresentationConfig.hpp +130 -0
  41. package/package.json +103 -0
  42. package/react-native.config.js +13 -0
  43. package/src/NativeSheetModal.tsx +343 -0
  44. package/src/index.ts +16 -0
  45. package/src/specs/SheetModalController.nitro.ts +54 -0
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { type ModalProps as RNModalProps } from 'react-native';
3
+ import type { PresentedModalConfig, PresentedModalDetent, SheetPresentationConfig } from './specs/SheetModalController.nitro';
4
+ export interface NativeSheetModalProps extends Pick<RNModalProps, 'children' | 'visible' | 'animationType' | 'presentationStyle' | 'onRequestClose' | 'onDismiss' | 'onShow' | 'allowSwipeDismissal'>, SheetPresentationConfig, Omit<PresentedModalConfig, 'modalInstanceId' | 'sheet'> {
5
+ onDetentChange?: (detent: PresentedModalDetent) => void;
6
+ }
7
+ export declare function applyPresentedModalConfig(config: PresentedModalConfig): boolean;
8
+ export declare function dismissPresentedNativeModal(animated?: boolean): boolean;
9
+ export declare function Modal(props: NativeSheetModalProps): React.JSX.Element | null;
10
+ export default Modal;
@@ -0,0 +1,243 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
2
+ import { Modal as RNModal, Platform, } from 'react-native';
3
+ import { getHybridObjectConstructor } from 'react-native-nitro-modules';
4
+ const APPLY_RETRY_LIMIT = 8;
5
+ const APPLY_RETRY_DELAY_MS = 16;
6
+ let cachedController = null;
7
+ let didFailToCreateController = false;
8
+ let nextModalInstanceId = 1;
9
+ function getSheetModalController() {
10
+ if (Platform.OS !== 'ios')
11
+ return null;
12
+ if (cachedController != null)
13
+ return cachedController;
14
+ if (didFailToCreateController)
15
+ return null;
16
+ try {
17
+ const SheetModalControllerCtor = getHybridObjectConstructor('SheetModalController');
18
+ cachedController = new SheetModalControllerCtor();
19
+ return cachedController;
20
+ }
21
+ catch {
22
+ didFailToCreateController = true;
23
+ return null;
24
+ }
25
+ }
26
+ function logDebug(instanceId, message, extra) {
27
+ if (!__DEV__)
28
+ return;
29
+ const tag = `[NativeSheetModal:${instanceId}]`;
30
+ if (extra != null) {
31
+ console.log(`${tag} ${message}`, extra);
32
+ }
33
+ else {
34
+ console.log(`${tag} ${message}`);
35
+ }
36
+ }
37
+ export function applyPresentedModalConfig(config) {
38
+ const controller = getSheetModalController();
39
+ if (controller == null)
40
+ return false;
41
+ return controller.applyPresentedModalConfig(config);
42
+ }
43
+ export function dismissPresentedNativeModal(animated = true) {
44
+ const controller = getSheetModalController();
45
+ if (controller == null)
46
+ return false;
47
+ return controller.dismissPresentedModal(animated);
48
+ }
49
+ export function Modal(props) {
50
+ const { children, visible, animationType, presentationStyle, onRequestClose, onDismiss: onDismissProp, onShow: onShowProp, allowSwipeDismissal, detents, customDetentHeights, selectedDetentIdentifier, selectedCustomDetentHeight, largestUndimmedDetentIdentifier, largestUndimmedCustomDetentHeight, prefersGrabberVisible, preferredCornerRadius, prefersScrollingExpandsWhenScrolledToEdge, prefersEdgeAttachedInCompactHeight, widthFollowsPreferredContentSizeWhenEdgeAttached, wantsFullScreen, isModalInPresentation, preferredContentWidth, preferredContentHeight, modalViewBackground, cornerConfiguration, onDetentChange, } = props;
51
+ const resolvedAllowSwipeDismissal = allowSwipeDismissal ??
52
+ (isModalInPresentation == null ? true : !isModalInPresentation);
53
+ const timeoutRef = useRef(null);
54
+ const detentPollIntervalRef = useRef(null);
55
+ const isVisibleRef = useRef(visible);
56
+ const prevVisibleRef = useRef(false);
57
+ const modalInstanceIdRef = useRef(nextModalInstanceId++);
58
+ const lastDetentKeyRef = useRef(null);
59
+ const nativeConfig = useMemo(() => {
60
+ const sheet = detents == null &&
61
+ customDetentHeights == null &&
62
+ selectedDetentIdentifier == null &&
63
+ selectedCustomDetentHeight == null &&
64
+ largestUndimmedDetentIdentifier == null &&
65
+ largestUndimmedCustomDetentHeight == null &&
66
+ prefersGrabberVisible == null &&
67
+ preferredCornerRadius == null &&
68
+ prefersScrollingExpandsWhenScrolledToEdge == null &&
69
+ prefersEdgeAttachedInCompactHeight == null &&
70
+ widthFollowsPreferredContentSizeWhenEdgeAttached == null &&
71
+ wantsFullScreen == null
72
+ ? undefined
73
+ : {
74
+ detents,
75
+ customDetentHeights,
76
+ selectedDetentIdentifier,
77
+ selectedCustomDetentHeight,
78
+ largestUndimmedDetentIdentifier,
79
+ largestUndimmedCustomDetentHeight,
80
+ prefersGrabberVisible,
81
+ preferredCornerRadius,
82
+ prefersScrollingExpandsWhenScrolledToEdge,
83
+ prefersEdgeAttachedInCompactHeight,
84
+ widthFollowsPreferredContentSizeWhenEdgeAttached,
85
+ wantsFullScreen,
86
+ };
87
+ return {
88
+ modalInstanceId: modalInstanceIdRef.current,
89
+ isModalInPresentation,
90
+ preferredContentWidth,
91
+ preferredContentHeight,
92
+ modalViewBackground: modalViewBackground ?? 'clear',
93
+ cornerConfiguration: cornerConfiguration ?? {
94
+ type: 'containerConcentric',
95
+ },
96
+ sheet,
97
+ };
98
+ }, [
99
+ detents,
100
+ customDetentHeights,
101
+ selectedDetentIdentifier,
102
+ selectedCustomDetentHeight,
103
+ largestUndimmedDetentIdentifier,
104
+ largestUndimmedCustomDetentHeight,
105
+ prefersGrabberVisible,
106
+ preferredCornerRadius,
107
+ prefersScrollingExpandsWhenScrolledToEdge,
108
+ prefersEdgeAttachedInCompactHeight,
109
+ widthFollowsPreferredContentSizeWhenEdgeAttached,
110
+ wantsFullScreen,
111
+ isModalInPresentation,
112
+ preferredContentWidth,
113
+ preferredContentHeight,
114
+ modalViewBackground,
115
+ cornerConfiguration,
116
+ ]);
117
+ const clearRetryTimeout = useCallback(() => {
118
+ if (timeoutRef.current != null) {
119
+ clearTimeout(timeoutRef.current);
120
+ timeoutRef.current = null;
121
+ logDebug(modalInstanceIdRef.current, 'cleared apply retry timeout');
122
+ }
123
+ }, []);
124
+ const clearDetentPollInterval = useCallback(() => {
125
+ if (detentPollIntervalRef.current != null) {
126
+ clearInterval(detentPollIntervalRef.current);
127
+ detentPollIntervalRef.current = null;
128
+ }
129
+ }, []);
130
+ useEffect(() => {
131
+ const wasVisible = prevVisibleRef.current;
132
+ prevVisibleRef.current = visible === true;
133
+ isVisibleRef.current = visible;
134
+ if (Platform.OS !== 'ios')
135
+ return;
136
+ if (!wasVisible && visible) {
137
+ const controller = getSheetModalController();
138
+ controller?.cachePresentedModalConfig(nativeConfig);
139
+ }
140
+ else if (wasVisible && !visible) {
141
+ logDebug(modalInstanceIdRef.current, 'visible=false: cleanup');
142
+ clearRetryTimeout();
143
+ clearDetentPollInterval();
144
+ lastDetentKeyRef.current = null;
145
+ }
146
+ }, [visible, nativeConfig, clearRetryTimeout, clearDetentPollInterval]);
147
+ const applyNativeConfigWithRetry = useCallback(() => {
148
+ if (Platform.OS !== 'ios' || !visible)
149
+ return;
150
+ const controller = getSheetModalController();
151
+ if (controller == null)
152
+ return;
153
+ clearRetryTimeout();
154
+ logDebug(modalInstanceIdRef.current, 'applyNativeConfigWithRetry start', {
155
+ visible,
156
+ selectedCustomDetentHeight,
157
+ largestUndimmedCustomDetentHeight,
158
+ detents,
159
+ customDetentHeights,
160
+ });
161
+ let attempts = 0;
162
+ const attempt = () => {
163
+ if (!isVisibleRef.current)
164
+ return;
165
+ const didApply = controller.applyPresentedModalConfig(nativeConfig);
166
+ attempts += 1;
167
+ logDebug(modalInstanceIdRef.current, 'applyPresentedModalConfig attempt', {
168
+ attempt: attempts,
169
+ didApply,
170
+ });
171
+ if (!didApply && attempts < APPLY_RETRY_LIMIT) {
172
+ timeoutRef.current = setTimeout(attempt, APPLY_RETRY_DELAY_MS);
173
+ }
174
+ };
175
+ attempt();
176
+ }, [
177
+ clearRetryTimeout,
178
+ customDetentHeights,
179
+ detents,
180
+ largestUndimmedCustomDetentHeight,
181
+ nativeConfig,
182
+ selectedCustomDetentHeight,
183
+ visible,
184
+ ]);
185
+ useEffect(() => {
186
+ applyNativeConfigWithRetry();
187
+ }, [applyNativeConfigWithRetry]);
188
+ useEffect(() => {
189
+ return () => {
190
+ clearRetryTimeout();
191
+ clearDetentPollInterval();
192
+ };
193
+ }, [clearDetentPollInterval, clearRetryTimeout]);
194
+ useEffect(() => {
195
+ if (Platform.OS !== 'ios')
196
+ return;
197
+ if (visible !== true || onDetentChange == null) {
198
+ clearDetentPollInterval();
199
+ return;
200
+ }
201
+ const controller = getSheetModalController();
202
+ if (controller == null)
203
+ return;
204
+ const poll = () => {
205
+ if (!isVisibleRef.current)
206
+ return;
207
+ const detent = controller.getPresentedModalDetent(modalInstanceIdRef.current);
208
+ if (detent == null)
209
+ return;
210
+ const detentKey = `${detent.rawDetentIdentifier ?? ''}|${detent.customDetentHeight ?? ''}`;
211
+ if (detentKey === lastDetentKeyRef.current)
212
+ return;
213
+ lastDetentKeyRef.current = detentKey;
214
+ logDebug(modalInstanceIdRef.current, 'emit onDetentChange', {
215
+ detentIdentifier: detent.detentIdentifier,
216
+ rawDetentIdentifier: detent.rawDetentIdentifier,
217
+ customDetentHeight: detent.customDetentHeight,
218
+ });
219
+ onDetentChange(detent);
220
+ };
221
+ clearDetentPollInterval();
222
+ poll();
223
+ detentPollIntervalRef.current = setInterval(poll, 80);
224
+ return () => {
225
+ clearDetentPollInterval();
226
+ };
227
+ }, [clearDetentPollInterval, onDetentChange, visible]);
228
+ const onShow = useCallback((event) => {
229
+ logDebug(modalInstanceIdRef.current, 'onShow');
230
+ applyNativeConfigWithRetry();
231
+ onShowProp?.(event);
232
+ }, [applyNativeConfigWithRetry, onShowProp]);
233
+ const onDismiss = useCallback(() => {
234
+ logDebug(modalInstanceIdRef.current, 'onDismiss');
235
+ clearRetryTimeout();
236
+ onDismissProp?.();
237
+ }, [clearRetryTimeout, onDismissProp]);
238
+ if (Platform.OS === 'ios' && !visible) {
239
+ return null;
240
+ }
241
+ return (React.createElement(RNModal, { visible: visible, animationType: animationType ?? 'slide', presentationStyle: presentationStyle ?? 'pageSheet', onRequestClose: onRequestClose, onDismiss: onDismiss, onShow: onShow, allowSwipeDismissal: resolvedAllowSwipeDismissal }, children));
242
+ }
243
+ export default Modal;
package/lib/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { Modal, Modal as NativeSheetModal, applyPresentedModalConfig, dismissPresentedNativeModal, } from './NativeSheetModal';
2
+ export type { NativeSheetModalProps } from './NativeSheetModal';
3
+ export type { ModalCornerConfiguration, ModalCornerConfigurationType, ModalViewBackground, PresentedModalConfig, PresentedModalDetent, SheetDetentIdentifier, SheetPresentationConfig, } from './specs/SheetModalController.nitro';
package/lib/index.js ADDED
@@ -0,0 +1 @@
1
+ export { Modal, Modal as NativeSheetModal, applyPresentedModalConfig, dismissPresentedNativeModal, } from './NativeSheetModal';
@@ -0,0 +1,46 @@
1
+ import type { HybridObject } from 'react-native-nitro-modules';
2
+ export type SheetDetentIdentifier = 'medium' | 'large';
3
+ export type ModalViewBackground = 'clear' | 'systemBackground';
4
+ export type ModalCornerConfigurationType = 'none' | 'fixed' | 'containerConcentric' | 'capsule';
5
+ export interface ModalCornerConfiguration {
6
+ type: ModalCornerConfigurationType;
7
+ radius?: number;
8
+ minimumRadius?: number;
9
+ maximumRadius?: number;
10
+ }
11
+ export interface SheetPresentationConfig {
12
+ detents?: SheetDetentIdentifier[];
13
+ customDetentHeights?: number[];
14
+ selectedDetentIdentifier?: SheetDetentIdentifier;
15
+ selectedCustomDetentHeight?: number;
16
+ largestUndimmedDetentIdentifier?: SheetDetentIdentifier;
17
+ largestUndimmedCustomDetentHeight?: number;
18
+ prefersGrabberVisible?: boolean;
19
+ preferredCornerRadius?: number;
20
+ prefersScrollingExpandsWhenScrolledToEdge?: boolean;
21
+ prefersEdgeAttachedInCompactHeight?: boolean;
22
+ widthFollowsPreferredContentSizeWhenEdgeAttached?: boolean;
23
+ wantsFullScreen?: boolean;
24
+ }
25
+ export interface PresentedModalConfig {
26
+ modalInstanceId?: number;
27
+ isModalInPresentation?: boolean;
28
+ preferredContentWidth?: number;
29
+ preferredContentHeight?: number;
30
+ modalViewBackground?: ModalViewBackground;
31
+ cornerConfiguration?: ModalCornerConfiguration;
32
+ sheet?: SheetPresentationConfig;
33
+ }
34
+ export interface PresentedModalDetent {
35
+ detentIdentifier?: SheetDetentIdentifier;
36
+ customDetentHeight?: number;
37
+ rawDetentIdentifier?: string;
38
+ }
39
+ export interface SheetModalController extends HybridObject<{
40
+ ios: 'swift';
41
+ }> {
42
+ cachePresentedModalConfig(config: PresentedModalConfig): boolean;
43
+ applyPresentedModalConfig(config: PresentedModalConfig): boolean;
44
+ getPresentedModalDetent(modalInstanceId: number): PresentedModalDetent | null;
45
+ dismissPresentedModal(animated: boolean): boolean;
46
+ }
@@ -0,0 +1 @@
1
+ export {};
package/nitro.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://nitro.margelo.com/nitro.schema.json",
3
+ "cxxNamespace": [
4
+ "concentricsheet"
5
+ ],
6
+ "ios": {
7
+ "iosModuleName": "NitroConcentricSheet"
8
+ },
9
+ "android": {
10
+ "androidNamespace": [
11
+ "concentricsheet"
12
+ ],
13
+ "androidCxxLibName": "NitroConcentricSheet"
14
+ },
15
+ "autolinking": {
16
+ "SheetModalController": {
17
+ "swift": "SheetModalController"
18
+ }
19
+ },
20
+ "ignorePaths": [
21
+ "**/node_modules"
22
+ ]
23
+ }
@@ -0,0 +1 @@
1
+ ** linguist-generated=true
@@ -0,0 +1,60 @@
1
+ #
2
+ # NitroConcentricSheet+autolinking.rb
3
+ # This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ # https://github.com/mrousavy/nitro
5
+ # Copyright © Marc Rousavy @ Margelo
6
+ #
7
+
8
+ # This is a Ruby script that adds all files generated by Nitrogen
9
+ # to the given podspec.
10
+ #
11
+ # To use it, add this to your .podspec:
12
+ # ```ruby
13
+ # Pod::Spec.new do |spec|
14
+ # # ...
15
+ #
16
+ # # Add all files generated by Nitrogen
17
+ # load 'nitrogen/generated/ios/NitroConcentricSheet+autolinking.rb'
18
+ # add_nitrogen_files(spec)
19
+ # end
20
+ # ```
21
+
22
+ def add_nitrogen_files(spec)
23
+ Pod::UI.puts "[NitroModules] 🔥 NitroConcentricSheet is boosted by nitro!"
24
+
25
+ spec.dependency "NitroModules"
26
+
27
+ current_source_files = Array(spec.attributes_hash['source_files'])
28
+ spec.source_files = current_source_files + [
29
+ # Generated cross-platform specs
30
+ "nitrogen/generated/shared/**/*.{h,hpp,c,cpp,swift}",
31
+ # Generated bridges for the cross-platform specs
32
+ "nitrogen/generated/ios/**/*.{h,hpp,c,cpp,mm,swift}",
33
+ ]
34
+
35
+ current_public_header_files = Array(spec.attributes_hash['public_header_files'])
36
+ spec.public_header_files = current_public_header_files + [
37
+ # Generated specs
38
+ "nitrogen/generated/shared/**/*.{h,hpp}",
39
+ # Swift to C++ bridging helpers
40
+ "nitrogen/generated/ios/NitroConcentricSheet-Swift-Cxx-Bridge.hpp"
41
+ ]
42
+
43
+ current_private_header_files = Array(spec.attributes_hash['private_header_files'])
44
+ spec.private_header_files = current_private_header_files + [
45
+ # iOS specific specs
46
+ "nitrogen/generated/ios/c++/**/*.{h,hpp}",
47
+ # Views are framework-specific and should be private
48
+ "nitrogen/generated/shared/**/views/**/*"
49
+ ]
50
+
51
+ current_pod_target_xcconfig = spec.attributes_hash['pod_target_xcconfig'] || {}
52
+ spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({
53
+ # Use C++ 20
54
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
55
+ # Enables C++ <-> Swift interop (by default it's only ObjC)
56
+ "SWIFT_OBJC_INTEROP_MODE" => "objcxx",
57
+ # Enables stricter modular headers
58
+ "DEFINES_MODULE" => "YES",
59
+ })
60
+ end
@@ -0,0 +1,33 @@
1
+ ///
2
+ /// NitroConcentricSheet-Swift-Cxx-Bridge.cpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #include "NitroConcentricSheet-Swift-Cxx-Bridge.hpp"
9
+
10
+ // Include C++ implementation defined types
11
+ #include "HybridSheetModalControllerSpecSwift.hpp"
12
+ #include "NitroConcentricSheet-Swift-Cxx-Umbrella.hpp"
13
+ #include <NitroModules/NitroDefines.hpp>
14
+
15
+ namespace margelo::nitro::concentricsheet::bridge::swift {
16
+
17
+ // pragma MARK: std::shared_ptr<HybridSheetModalControllerSpec>
18
+ std::shared_ptr<HybridSheetModalControllerSpec> create_std__shared_ptr_HybridSheetModalControllerSpec_(void* NON_NULL swiftUnsafePointer) noexcept {
19
+ NitroConcentricSheet::HybridSheetModalControllerSpec_cxx swiftPart = NitroConcentricSheet::HybridSheetModalControllerSpec_cxx::fromUnsafe(swiftUnsafePointer);
20
+ return std::make_shared<margelo::nitro::concentricsheet::HybridSheetModalControllerSpecSwift>(swiftPart);
21
+ }
22
+ void* NON_NULL get_std__shared_ptr_HybridSheetModalControllerSpec_(std__shared_ptr_HybridSheetModalControllerSpec_ cppType) {
23
+ std::shared_ptr<margelo::nitro::concentricsheet::HybridSheetModalControllerSpecSwift> swiftWrapper = std::dynamic_pointer_cast<margelo::nitro::concentricsheet::HybridSheetModalControllerSpecSwift>(cppType);
24
+ #ifdef NITRO_DEBUG
25
+ if (swiftWrapper == nullptr) [[unlikely]] {
26
+ throw std::runtime_error("Class \"HybridSheetModalControllerSpec\" is not implemented in Swift!");
27
+ }
28
+ #endif
29
+ NitroConcentricSheet::HybridSheetModalControllerSpec_cxx& swiftPart = swiftWrapper->getSwiftPart();
30
+ return swiftPart.toUnsafe();
31
+ }
32
+
33
+ } // namespace margelo::nitro::concentricsheet::bridge::swift