@lodev09/react-native-true-sheet 0.9.7 → 0.9.9
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.
- package/README.md +120 -18
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +199 -29
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +44 -48
- package/android/src/main/java/com/lodev09/truesheet/core/{RootViewGroup.kt → RootSheetView.kt} +3 -8
- package/ios/TrueSheetView.swift +0 -3
- package/lib/commonjs/TrueSheet.js +59 -25
- package/lib/commonjs/TrueSheet.js.map +1 -1
- package/lib/commonjs/TrueSheetFooter.js +20 -0
- package/lib/commonjs/TrueSheetFooter.js.map +1 -0
- package/lib/commonjs/__mocks__/index.js +3 -0
- package/lib/commonjs/__mocks__/index.js.map +1 -1
- package/lib/module/TrueSheet.js +58 -24
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheetFooter.js +12 -0
- package/lib/module/TrueSheetFooter.js.map +1 -0
- package/lib/module/__mocks__/index.js +3 -0
- package/lib/module/__mocks__/index.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +23 -3
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetFooter.d.ts +8 -0
- package/lib/typescript/src/TrueSheetFooter.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +15 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TrueSheet.tsx +74 -37
- package/src/TrueSheetFooter.tsx +18 -0
- package/src/__mocks__/index.js +4 -0
- package/src/types.ts +15 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetBehavior.kt +0 -230
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export const TrueSheetFooter = props => {
|
|
3
|
+
const {
|
|
4
|
+
Component
|
|
5
|
+
} = props;
|
|
6
|
+
if (!Component) return null;
|
|
7
|
+
if (typeof Component !== 'function') {
|
|
8
|
+
return Component;
|
|
9
|
+
}
|
|
10
|
+
return /*#__PURE__*/React.createElement(Component, null);
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=TrueSheetFooter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","TrueSheetFooter","props","Component","createElement"],"sourceRoot":"../../src","sources":["TrueSheetFooter.tsx"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAOzB,OAAO,MAAMC,eAAe,GAAIC,KAA2B,IAAK;EAC9D,MAAM;IAAEC;EAAU,CAAC,GAAGD,KAAK;EAE3B,IAAI,CAACC,SAAS,EAAE,OAAO,IAAI;EAE3B,IAAI,OAAOA,SAAS,KAAK,UAAU,EAAE;IACnC,OAAOA,SAAS;EAClB;EAEA,oBAAOH,KAAA,CAAAI,aAAA,CAACD,SAAS,MAAE,CAAC;AACtB,CAAC","ignoreList":[]}
|
|
@@ -2,6 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
export * from '../TrueSheetGrabber';
|
|
4
4
|
export class TrueSheet extends React.Component {
|
|
5
|
+
static dismiss = jest.fn();
|
|
6
|
+
static present = jest.fn();
|
|
7
|
+
static resize = jest.fn();
|
|
5
8
|
dismiss = jest.fn();
|
|
6
9
|
present = jest.fn();
|
|
7
10
|
resize = jest.fn();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","View","TrueSheet","Component","dismiss","jest","fn","present","resize","render","createElement","props"],"sourceRoot":"../../../src","sources":["__mocks__/index.js"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AAEnC,cAAc,qBAAqB;AAEnC,OAAO,MAAMC,SAAS,SAASF,KAAK,CAACG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"names":["React","View","TrueSheet","Component","dismiss","jest","fn","present","resize","render","createElement","props"],"sourceRoot":"../../../src","sources":["__mocks__/index.js"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AAEnC,cAAc,qBAAqB;AAEnC,OAAO,MAAMC,SAAS,SAASF,KAAK,CAACG,SAAS,CAAC;EAC7C,OAAOC,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAC,CAAC;EAC1B,OAAOC,OAAO,GAAGF,IAAI,CAACC,EAAE,CAAC,CAAC;EAC1B,OAAOE,MAAM,GAAGH,IAAI,CAACC,EAAE,CAAC,CAAC;EAEzBF,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAC,CAAC;EACnBC,OAAO,GAAGF,IAAI,CAACC,EAAE,CAAC,CAAC;EACnBE,MAAM,GAAGH,IAAI,CAACC,EAAE,CAAC,CAAC;EAElBG,MAAMA,CAAA,EAAG;IACP,oBAAOT,KAAA,CAAAU,aAAA,CAACT,IAAI,EAAK,IAAI,CAACU,KAAQ,CAAC;EACjC;AACF","ignoreList":[]}
|
|
@@ -6,16 +6,34 @@ interface TrueSheetState {
|
|
|
6
6
|
export declare class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
7
7
|
displayName: string;
|
|
8
8
|
private readonly ref;
|
|
9
|
+
/**
|
|
10
|
+
* Map of sheet names against their handle.
|
|
11
|
+
*/
|
|
12
|
+
private static readonly handles;
|
|
9
13
|
constructor(props: TrueSheetProps);
|
|
14
|
+
private static getHandle;
|
|
15
|
+
/**
|
|
16
|
+
* Present the sheet by given `name`.
|
|
17
|
+
* See `name` prop.
|
|
18
|
+
*/
|
|
19
|
+
static present(name: string, index?: number): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Dismiss the sheet by given `name`.
|
|
22
|
+
* See `name` prop.
|
|
23
|
+
*/
|
|
24
|
+
static dismiss(name: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Resize the sheet by given `name`.
|
|
27
|
+
* See `name` prop.
|
|
28
|
+
*/
|
|
29
|
+
static resize(name: string, index: number): Promise<void>;
|
|
10
30
|
private get handle();
|
|
11
31
|
private updateState;
|
|
12
32
|
private onSizeChange;
|
|
13
33
|
private onPresent;
|
|
14
34
|
private onDismiss;
|
|
15
|
-
componentDidMount(): void;
|
|
16
|
-
componentDidUpdate(): void;
|
|
17
35
|
/**
|
|
18
|
-
* Present the
|
|
36
|
+
* Present the sheet. Optionally accepts a size `index`.
|
|
19
37
|
* See `sizes` prop
|
|
20
38
|
*/
|
|
21
39
|
present(index?: number): Promise<void>;
|
|
@@ -28,6 +46,8 @@ export declare class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetSt
|
|
|
28
46
|
* Dismisses the Sheet
|
|
29
47
|
*/
|
|
30
48
|
dismiss(): Promise<void>;
|
|
49
|
+
componentDidMount(): void;
|
|
50
|
+
componentDidUpdate(): void;
|
|
31
51
|
render(): ReactNode;
|
|
32
52
|
}
|
|
33
53
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrueSheet.d.ts","sourceRoot":"","sources":["../../../src/TrueSheet.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAWlG,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"TrueSheet.d.ts","sourceRoot":"","sources":["../../../src/TrueSheet.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAWlG,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,SAAS,CAAA;AAoBvD,UAAU,cAAc;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAQD,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC;IAC1E,WAAW,SAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;IAE1C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAiC;gBAEpD,KAAK,EAAE,cAAc;IAcjC,OAAO,CAAC,MAAM,CAAC,SAAS;IAUxB;;;OAGG;WACiB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU;IAO3D;;;OAGG;WACiB,OAAO,CAAC,IAAI,EAAE,MAAM;IAOxC;;;OAGG;WACiB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAItD,OAAO,KAAK,MAAM,GAOjB;IAED,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IAIjB;;;OAGG;IACU,OAAO,CAAC,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;;OAGG;IACU,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,iBAAiB,IAAI,IAAI;IAUzB,kBAAkB,IAAI,IAAI;IAI1B,MAAM,IAAI,SAAS;CA6DpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TrueSheetProps } from './types';
|
|
3
|
+
interface TrueSheetFooterProps {
|
|
4
|
+
Component?: TrueSheetProps['FooterComponent'];
|
|
5
|
+
}
|
|
6
|
+
export declare const TrueSheetFooter: (props: TrueSheetFooterProps) => React.JSX.Element | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=TrueSheetFooter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrueSheetFooter.d.ts","sourceRoot":"","sources":["../../../src/TrueSheetFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,UAAU,oBAAoB;IAC5B,SAAS,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;CAC9C;AAED,eAAO,MAAM,eAAe,UAAW,oBAAoB,6BAU1D,CAAA"}
|
|
@@ -61,6 +61,21 @@ export type SheetSize =
|
|
|
61
61
|
*/
|
|
62
62
|
| 'large';
|
|
63
63
|
export interface TrueSheetProps extends ViewProps {
|
|
64
|
+
/**
|
|
65
|
+
* The name to reference this sheet. It has to be unique.
|
|
66
|
+
* You can then present this sheet globally using its `name`.
|
|
67
|
+
*
|
|
68
|
+
* Example:
|
|
69
|
+
* ```ts
|
|
70
|
+
* <TrueSheet name="my-awesome-sheet">
|
|
71
|
+
* <MyComponent />
|
|
72
|
+
* </TrueSheet>
|
|
73
|
+
* ```
|
|
74
|
+
* ```ts
|
|
75
|
+
* TrueSheet.present('my-awesome-sheet')
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
name?: string;
|
|
64
79
|
/**
|
|
65
80
|
* The sizes you want the Sheet to support.
|
|
66
81
|
* Maximum of 3 sizes only; collapsed, half-expanded, expanded.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAE/D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,WAAW,GACX,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,qBAAqB,GACrB,sBAAsB,GACtB,8BAA8B,GAC9B,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAC1B,2BAA2B,GAC3B,6BAA6B,GAC7B,wBAAwB,GACxB,oBAAoB,GACpB,yBAAyB,GACzB,0BAA0B,CAAA;AAE9B;;;;;GAKG;AACH,MAAM,MAAM,SAAS;AACnB;;;;;GAKG;AACD,MAAM;AAER;;;;;GAKG;GACD,MAAM;AAER;;;;;GAKG;GACD,GAAG,MAAM,GAAG;AAEd;;;;;GAKG;GACD,OAAO;AAET;;;;;GAKG;GACD,QAAQ;AAEV;;;;;GAKG;GACD,OAAO,CAAA;AAEX,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,eAAe,CAAC,EAAE,UAAU,CAAA;IAE5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAEnB;;OAEG;IACH,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IAE5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAEzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,YAAY,CAAA;IAEvD;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;IAEpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;CACxC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAE/D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,WAAW,GACX,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,qBAAqB,GACrB,sBAAsB,GACtB,8BAA8B,GAC9B,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAC1B,2BAA2B,GAC3B,6BAA6B,GAC7B,wBAAwB,GACxB,oBAAoB,GACpB,yBAAyB,GACzB,0BAA0B,CAAA;AAE9B;;;;;GAKG;AACH,MAAM,MAAM,SAAS;AACnB;;;;;GAKG;AACD,MAAM;AAER;;;;;GAKG;GACD,MAAM;AAER;;;;;GAKG;GACD,GAAG,MAAM,GAAG;AAEd;;;;;GAKG;GACD,OAAO;AAET;;;;;GAKG;GACD,QAAQ;AAEV;;;;;GAKG;GACD,OAAO,CAAA;AAEX,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,eAAe,CAAC,EAAE,UAAU,CAAA;IAE5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAEnB;;OAEG;IACH,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IAE5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAEzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,YAAY,CAAA;IAEvD;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;IAEpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;CACxC"}
|
package/package.json
CHANGED
package/src/TrueSheet.tsx
CHANGED
|
@@ -12,38 +12,43 @@ import {
|
|
|
12
12
|
import type { TrueSheetProps, SizeInfo } from './types'
|
|
13
13
|
import { TrueSheetModule } from './TrueSheetModule'
|
|
14
14
|
import { TrueSheetGrabber } from './TrueSheetGrabber'
|
|
15
|
+
import { TrueSheetFooter } from './TrueSheetFooter'
|
|
15
16
|
|
|
17
|
+
const NATIVE_COMPONENT_NAME = 'TrueSheetView'
|
|
16
18
|
const LINKING_ERROR =
|
|
17
19
|
`The package '@lodev09/react-native-true-sheet' doesn't seem to be linked. Make sure: \n\n` +
|
|
18
20
|
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
19
21
|
'- You rebuilt the app after installing the package\n' +
|
|
20
22
|
'- You are not using Expo Go\n'
|
|
21
23
|
|
|
22
|
-
const ComponentName = 'TrueSheetView'
|
|
23
|
-
|
|
24
24
|
interface TrueSheetNativeViewProps extends Omit<TrueSheetProps, 'onPresent' | 'onSizeChange'> {
|
|
25
25
|
scrollableHandle: number | null
|
|
26
26
|
onPresent: (event: NativeSyntheticEvent<SizeInfo>) => void
|
|
27
27
|
onSizeChange: (event: NativeSyntheticEvent<SizeInfo>) => void
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const TrueSheetNativeView = requireNativeComponent<TrueSheetNativeViewProps>(ComponentName)
|
|
31
|
-
|
|
32
|
-
if (!TrueSheetNativeView) {
|
|
33
|
-
throw new Error(LINKING_ERROR)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
30
|
type NativeRef = Component<TrueSheetNativeViewProps> & Readonly<NativeMethods>
|
|
37
31
|
|
|
38
32
|
interface TrueSheetState {
|
|
39
33
|
scrollableHandle: number | null
|
|
40
34
|
}
|
|
41
35
|
|
|
36
|
+
const TrueSheetNativeView = requireNativeComponent<TrueSheetNativeViewProps>(NATIVE_COMPONENT_NAME)
|
|
37
|
+
|
|
38
|
+
if (!TrueSheetNativeView) {
|
|
39
|
+
throw new Error(LINKING_ERROR)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
42
|
export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
43
43
|
displayName = 'TrueSheet'
|
|
44
44
|
|
|
45
45
|
private readonly ref: RefObject<NativeRef>
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Map of sheet names against their handle.
|
|
49
|
+
*/
|
|
50
|
+
private static readonly handles: { [name: string]: number } = {}
|
|
51
|
+
|
|
47
52
|
constructor(props: TrueSheetProps) {
|
|
48
53
|
super(props)
|
|
49
54
|
|
|
@@ -58,10 +63,50 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
58
63
|
}
|
|
59
64
|
}
|
|
60
65
|
|
|
66
|
+
private static getHandle(name: string) {
|
|
67
|
+
const handle = TrueSheet.handles[name]
|
|
68
|
+
if (!handle) {
|
|
69
|
+
console.warn(`Could not get native view tag from "${name}". Check your name prop.`)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return handle
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Present the sheet by given `name`.
|
|
78
|
+
* See `name` prop.
|
|
79
|
+
*/
|
|
80
|
+
public static async present(name: string, index: number = 0) {
|
|
81
|
+
const handle = TrueSheet.getHandle(name)
|
|
82
|
+
if (!handle) return
|
|
83
|
+
|
|
84
|
+
await TrueSheetModule.present(handle, index)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Dismiss the sheet by given `name`.
|
|
89
|
+
* See `name` prop.
|
|
90
|
+
*/
|
|
91
|
+
public static async dismiss(name: string) {
|
|
92
|
+
const handle = TrueSheet.getHandle(name)
|
|
93
|
+
if (!handle) return
|
|
94
|
+
|
|
95
|
+
await TrueSheetModule.dismiss(handle)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Resize the sheet by given `name`.
|
|
100
|
+
* See `name` prop.
|
|
101
|
+
*/
|
|
102
|
+
public static async resize(name: string, index: number) {
|
|
103
|
+
await TrueSheet.present(name, index)
|
|
104
|
+
}
|
|
105
|
+
|
|
61
106
|
private get handle(): number {
|
|
62
107
|
const nodeHandle = findNodeHandle(this.ref.current)
|
|
63
108
|
if (nodeHandle == null || nodeHandle === -1) {
|
|
64
|
-
throw new Error(
|
|
109
|
+
throw new Error('Could not get native view tag')
|
|
65
110
|
}
|
|
66
111
|
|
|
67
112
|
return nodeHandle
|
|
@@ -72,6 +117,10 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
72
117
|
? findNodeHandle(this.props.scrollRef.current)
|
|
73
118
|
: null
|
|
74
119
|
|
|
120
|
+
if (this.props.name) {
|
|
121
|
+
TrueSheet.handles[this.props.name] = this.handle
|
|
122
|
+
}
|
|
123
|
+
|
|
75
124
|
this.setState({
|
|
76
125
|
scrollableHandle,
|
|
77
126
|
})
|
|
@@ -89,22 +138,8 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
89
138
|
this.props.onDismiss?.()
|
|
90
139
|
}
|
|
91
140
|
|
|
92
|
-
componentDidMount(): void {
|
|
93
|
-
if (this.props.sizes && this.props.sizes.length > 3) {
|
|
94
|
-
console.warn(
|
|
95
|
-
'TrueSheet only supports a maximum of 3 sizes; collapsed, half-expanded and expanded. Check your `sizes` prop.'
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this.updateState()
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
componentDidUpdate(): void {
|
|
103
|
-
this.updateState()
|
|
104
|
-
}
|
|
105
|
-
|
|
106
141
|
/**
|
|
107
|
-
* Present the
|
|
142
|
+
* Present the sheet. Optionally accepts a size `index`.
|
|
108
143
|
* See `sizes` prop
|
|
109
144
|
*/
|
|
110
145
|
public async present(index: number = 0): Promise<void> {
|
|
@@ -126,6 +161,20 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
126
161
|
await TrueSheetModule.dismiss(this.handle)
|
|
127
162
|
}
|
|
128
163
|
|
|
164
|
+
componentDidMount(): void {
|
|
165
|
+
if (this.props.sizes && this.props.sizes.length > 3) {
|
|
166
|
+
console.warn(
|
|
167
|
+
'TrueSheet only supports a maximum of 3 sizes; collapsed, half-expanded and expanded. Check your `sizes` prop.'
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.updateState()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
componentDidUpdate(): void {
|
|
175
|
+
this.updateState()
|
|
176
|
+
}
|
|
177
|
+
|
|
129
178
|
render(): ReactNode {
|
|
130
179
|
const {
|
|
131
180
|
sizes = ['medium', 'large'],
|
|
@@ -180,7 +229,7 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
180
229
|
{children}
|
|
181
230
|
</View>
|
|
182
231
|
<View collapsable={false}>
|
|
183
|
-
<TrueSheetFooter
|
|
232
|
+
<TrueSheetFooter Component={FooterComponent} />
|
|
184
233
|
</View>
|
|
185
234
|
{Platform.OS === 'android' && <TrueSheetGrabber visible={grabber} {...grabberProps} />}
|
|
186
235
|
</View>
|
|
@@ -189,18 +238,6 @@ export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
|
189
238
|
}
|
|
190
239
|
}
|
|
191
240
|
|
|
192
|
-
const TrueSheetFooter = (props: Pick<TrueSheetProps, 'FooterComponent'>) => {
|
|
193
|
-
const { FooterComponent } = props
|
|
194
|
-
|
|
195
|
-
if (!FooterComponent) return null
|
|
196
|
-
|
|
197
|
-
if (typeof FooterComponent !== 'function') {
|
|
198
|
-
return FooterComponent
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return <FooterComponent />
|
|
202
|
-
}
|
|
203
|
-
|
|
204
241
|
const $nativeSheet: ViewStyle = {
|
|
205
242
|
position: 'absolute',
|
|
206
243
|
left: -9999,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { TrueSheetProps } from './types'
|
|
3
|
+
|
|
4
|
+
interface TrueSheetFooterProps {
|
|
5
|
+
Component?: TrueSheetProps['FooterComponent']
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const TrueSheetFooter = (props: TrueSheetFooterProps) => {
|
|
9
|
+
const { Component } = props
|
|
10
|
+
|
|
11
|
+
if (!Component) return null
|
|
12
|
+
|
|
13
|
+
if (typeof Component !== 'function') {
|
|
14
|
+
return Component
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return <Component />
|
|
18
|
+
}
|
package/src/__mocks__/index.js
CHANGED
|
@@ -4,6 +4,10 @@ import { View } from 'react-native'
|
|
|
4
4
|
export * from '../TrueSheetGrabber'
|
|
5
5
|
|
|
6
6
|
export class TrueSheet extends React.Component {
|
|
7
|
+
static dismiss = jest.fn()
|
|
8
|
+
static present = jest.fn()
|
|
9
|
+
static resize = jest.fn()
|
|
10
|
+
|
|
7
11
|
dismiss = jest.fn()
|
|
8
12
|
present = jest.fn()
|
|
9
13
|
resize = jest.fn()
|
package/src/types.ts
CHANGED
|
@@ -92,6 +92,21 @@ export type SheetSize =
|
|
|
92
92
|
| 'large'
|
|
93
93
|
|
|
94
94
|
export interface TrueSheetProps extends ViewProps {
|
|
95
|
+
/**
|
|
96
|
+
* The name to reference this sheet. It has to be unique.
|
|
97
|
+
* You can then present this sheet globally using its `name`.
|
|
98
|
+
*
|
|
99
|
+
* Example:
|
|
100
|
+
* ```ts
|
|
101
|
+
* <TrueSheet name="my-awesome-sheet">
|
|
102
|
+
* <MyComponent />
|
|
103
|
+
* </TrueSheet>
|
|
104
|
+
* ```
|
|
105
|
+
* ```ts
|
|
106
|
+
* TrueSheet.present('my-awesome-sheet')
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
name?: string
|
|
95
110
|
/**
|
|
96
111
|
* The sizes you want the Sheet to support.
|
|
97
112
|
* Maximum of 3 sizes only; collapsed, half-expanded, expanded.
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
package com.lodev09.truesheet
|
|
2
|
-
|
|
3
|
-
import android.view.MotionEvent
|
|
4
|
-
import android.view.ViewGroup
|
|
5
|
-
import android.widget.ScrollView
|
|
6
|
-
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
7
|
-
import com.facebook.react.bridge.ReactContext
|
|
8
|
-
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
9
|
-
import com.lodev09.truesheet.core.Utils
|
|
10
|
-
|
|
11
|
-
data class SizeInfo(val index: Int, val value: Float)
|
|
12
|
-
|
|
13
|
-
class TrueSheetBehavior(private val reactContext: ReactContext) : BottomSheetBehavior<ViewGroup>() {
|
|
14
|
-
var maxScreenHeight: Int = 0
|
|
15
|
-
var maxSheetHeight: Int? = null
|
|
16
|
-
|
|
17
|
-
var contentView: ViewGroup? = null
|
|
18
|
-
var footerView: ViewGroup? = null
|
|
19
|
-
|
|
20
|
-
var sizes: Array<Any> = arrayOf("medium", "large")
|
|
21
|
-
|
|
22
|
-
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: ViewGroup, event: MotionEvent): Boolean {
|
|
23
|
-
contentView?.let {
|
|
24
|
-
val isDownEvent = (event.actionMasked == MotionEvent.ACTION_DOWN)
|
|
25
|
-
val expanded = state == STATE_EXPANDED
|
|
26
|
-
|
|
27
|
-
if (isDownEvent && expanded) {
|
|
28
|
-
for (i in 0 until it.childCount) {
|
|
29
|
-
val contentChild = it.getChildAt(i)
|
|
30
|
-
val scrolled = (contentChild is ScrollView && contentChild.scrollY > 0)
|
|
31
|
-
|
|
32
|
-
if (!scrolled) continue
|
|
33
|
-
if (isInsideSheet(contentChild as ScrollView, event)) {
|
|
34
|
-
return false
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return super.onInterceptTouchEvent(parent, child, event)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
private fun isInsideSheet(scrollView: ScrollView, event: MotionEvent): Boolean {
|
|
44
|
-
val x = event.x
|
|
45
|
-
val y = event.y
|
|
46
|
-
|
|
47
|
-
val position = IntArray(2)
|
|
48
|
-
scrollView.getLocationOnScreen(position)
|
|
49
|
-
|
|
50
|
-
val nestedX = position[0]
|
|
51
|
-
val nestedY = position[1]
|
|
52
|
-
|
|
53
|
-
val boundRight = nestedX + scrollView.width
|
|
54
|
-
val boundBottom = nestedY + scrollView.height
|
|
55
|
-
|
|
56
|
-
return (x > nestedX && x < boundRight && y > nestedY && y < boundBottom) ||
|
|
57
|
-
event.action == MotionEvent.ACTION_CANCEL
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Get the height value based on the size config value.
|
|
62
|
-
*/
|
|
63
|
-
private fun getSizeHeight(size: Any, contentHeight: Int): Int {
|
|
64
|
-
val height =
|
|
65
|
-
when (size) {
|
|
66
|
-
is Double -> Utils.toPixel(size)
|
|
67
|
-
|
|
68
|
-
is Int -> Utils.toPixel(size.toDouble())
|
|
69
|
-
|
|
70
|
-
is String -> {
|
|
71
|
-
when (size) {
|
|
72
|
-
"auto" -> contentHeight
|
|
73
|
-
|
|
74
|
-
"large" -> maxScreenHeight
|
|
75
|
-
|
|
76
|
-
"medium" -> (maxScreenHeight * 0.50).toInt()
|
|
77
|
-
|
|
78
|
-
"small" -> (maxScreenHeight * 0.25).toInt()
|
|
79
|
-
|
|
80
|
-
else -> {
|
|
81
|
-
if (size.endsWith('%')) {
|
|
82
|
-
val percent = size.trim('%').toDoubleOrNull()
|
|
83
|
-
if (percent == null) {
|
|
84
|
-
0
|
|
85
|
-
} else {
|
|
86
|
-
((percent / 100) * maxScreenHeight).toInt()
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
val fixedHeight = size.toDoubleOrNull()
|
|
90
|
-
if (fixedHeight == null) {
|
|
91
|
-
0
|
|
92
|
-
} else {
|
|
93
|
-
Utils.toPixel(fixedHeight)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
else -> (maxScreenHeight * 0.5).toInt()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return minOf(height, maxSheetHeight ?: maxScreenHeight)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Determines the state based on the given size index.
|
|
108
|
-
*/
|
|
109
|
-
fun getStateForSizeIndex(index: Int) =
|
|
110
|
-
when (sizes.size) {
|
|
111
|
-
1 -> STATE_EXPANDED
|
|
112
|
-
|
|
113
|
-
2 -> {
|
|
114
|
-
when (index) {
|
|
115
|
-
0 -> STATE_COLLAPSED
|
|
116
|
-
1 -> STATE_EXPANDED
|
|
117
|
-
else -> STATE_HIDDEN
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
3 -> {
|
|
122
|
-
when (index) {
|
|
123
|
-
0 -> STATE_COLLAPSED
|
|
124
|
-
1 -> STATE_HALF_EXPANDED
|
|
125
|
-
2 -> STATE_EXPANDED
|
|
126
|
-
else -> STATE_HIDDEN
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
else -> STATE_HIDDEN
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Configure the sheet based on size preferences.
|
|
135
|
-
*/
|
|
136
|
-
fun configure() {
|
|
137
|
-
// Update the usable sheet height
|
|
138
|
-
maxScreenHeight = Utils.screenHeight(reactContext)
|
|
139
|
-
|
|
140
|
-
var contentHeight = 0
|
|
141
|
-
|
|
142
|
-
contentView?.let { contentHeight = it.height }
|
|
143
|
-
footerView?.let { contentHeight += it.height }
|
|
144
|
-
|
|
145
|
-
// Configure sheet sizes
|
|
146
|
-
apply {
|
|
147
|
-
skipCollapsed = false
|
|
148
|
-
isFitToContents = true
|
|
149
|
-
|
|
150
|
-
// m3 max width 640dp
|
|
151
|
-
maxWidth = Utils.toPixel(640.0)
|
|
152
|
-
|
|
153
|
-
when (sizes.size) {
|
|
154
|
-
1 -> {
|
|
155
|
-
maxHeight = getSizeHeight(sizes[0], contentHeight)
|
|
156
|
-
peekHeight = maxHeight
|
|
157
|
-
skipCollapsed = true
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
2 -> {
|
|
161
|
-
peekHeight = getSizeHeight(sizes[0], contentHeight)
|
|
162
|
-
maxHeight = getSizeHeight(sizes[1], contentHeight)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
3 -> {
|
|
166
|
-
// Enables half expanded
|
|
167
|
-
isFitToContents = false
|
|
168
|
-
|
|
169
|
-
peekHeight = getSizeHeight(sizes[0], contentHeight)
|
|
170
|
-
halfExpandedRatio = getSizeHeight(sizes[1], contentHeight).toFloat() / maxScreenHeight.toFloat()
|
|
171
|
-
maxHeight = getSizeHeight(sizes[2], contentHeight)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Get the SizeInfo data by state.
|
|
179
|
-
*/
|
|
180
|
-
fun getSizeInfoForState(state: Int): SizeInfo? =
|
|
181
|
-
when (sizes.size) {
|
|
182
|
-
1 -> {
|
|
183
|
-
when (state) {
|
|
184
|
-
STATE_EXPANDED -> SizeInfo(0, Utils.toDIP(maxHeight))
|
|
185
|
-
else -> null
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
2 -> {
|
|
190
|
-
when (state) {
|
|
191
|
-
STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(peekHeight))
|
|
192
|
-
STATE_EXPANDED -> SizeInfo(1, Utils.toDIP(maxHeight))
|
|
193
|
-
else -> null
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
3 -> {
|
|
198
|
-
when (state) {
|
|
199
|
-
STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(peekHeight))
|
|
200
|
-
|
|
201
|
-
STATE_HALF_EXPANDED -> {
|
|
202
|
-
val height = halfExpandedRatio * maxScreenHeight
|
|
203
|
-
SizeInfo(1, Utils.toDIP(height.toInt()))
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
STATE_EXPANDED -> SizeInfo(2, Utils.toDIP(maxHeight))
|
|
207
|
-
|
|
208
|
-
else -> null
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
else -> null
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Get SizeInfo data for given size index.
|
|
217
|
-
*/
|
|
218
|
-
fun getSizeInfoForIndex(index: Int) = getSizeInfoForState(getStateForSizeIndex(index)) ?: SizeInfo(0, 0f)
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Set the state based on the given size index.
|
|
222
|
-
*/
|
|
223
|
-
fun setStateForSizeIndex(index: Int) {
|
|
224
|
-
state = getStateForSizeIndex(index)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
companion object {
|
|
228
|
-
const val TAG = "TrueSheetView"
|
|
229
|
-
}
|
|
230
|
-
}
|