Skip to content

Commit 03a4efb

Browse files
committed
feat(bottomsheet): svelte!
1 parent 70e3d50 commit 03a4efb

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/bottomsheet/svelte/index.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { BottomSheetOptions } from '@nativescript-community/ui-material-bottomsheet';
2+
import { Frame, View, ViewBase } from '@nativescript/core';
3+
import { NativeViewElementNode, createElement } from 'svelte-native/dom';
4+
import { PageSpec } from 'svelte-native/dom/navigation';
5+
6+
export interface ShowBottomSheetOptions extends Omit<BottomSheetOptions, 'view'> {
7+
view: PageSpec;
8+
parent: NativeViewElementNode<View> | View;
9+
props?: any;
10+
}
11+
interface ComponentInstanceInfo {
12+
element: NativeViewElementNode<View>;
13+
viewInstance: SvelteComponent;
14+
}
15+
16+
const modalStack: ComponentInstanceInfo[] = [];
17+
18+
export function resolveComponentElement(viewSpec: PageSpec, props?: any): ComponentInstanceInfo {
19+
const dummy = createElement('fragment');
20+
const viewInstance = new viewSpec({ target: dummy, props });
21+
const element = dummy.firstElement() as NativeViewElementNode<View>;
22+
return { element, viewInstance };
23+
}
24+
25+
export function showBottomSheet<T>(modalOptions: ShowBottomSheetOptions): Promise<T> {
26+
const { view, parent, props = {}, ...options } = modalOptions;
27+
// Get this before any potential new frames are created by component below
28+
const modalLauncher = (parent && (parent instanceof View ? parent : parent.nativeView)) || Frame.topmost().currentPage;
29+
30+
const componentInstanceInfo = resolveComponentElement(view, props);
31+
const modalView: ViewBase = componentInstanceInfo.element.nativeView;
32+
33+
return new Promise(async (resolve, reject) => {
34+
let resolved = false;
35+
const closeCallback = (result: T) => {
36+
if (resolved) return;
37+
const index = modalStack.indexOf(componentInstanceInfo);
38+
if (index !== -1) {
39+
modalStack.splice(index, 1);
40+
}
41+
resolved = true;
42+
resolve(result);
43+
componentInstanceInfo.viewInstance.$destroy(); // don't let an exception in destroy kill the promise callback
44+
};
45+
try {
46+
modalLauncher.showBottomSheet({ view: modalView, ...options, context: {}, closeCallback });
47+
modalStack.push(componentInstanceInfo);
48+
} catch (err) {
49+
reject(err);
50+
}
51+
});
52+
}
53+
54+
export function closeBottomSheet(result?: any): void {
55+
const modalPageInstanceInfo = modalStack[modalStack.length - 1];
56+
if (modalPageInstanceInfo) {
57+
(modalPageInstanceInfo.element.nativeView as any).closeBottomSheet(result);
58+
}
59+
}
60+
export function isBottomSheetOpened() {
61+
return modalStack.length > 0;
62+
}

0 commit comments

Comments
 (0)