@ohos-ports/react-native-root-siblings 5.0.1-beta.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) [2015-2016] [Horcrux]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ ## react-native-root-siblings [![npm version](https://badge.fury.io/js/react-native-root-siblings.svg)](http://badge.fury.io/js/react-native-root-siblings)
2
+
3
+ The easiest way to create overlays(`Modal`, `Popover`, `Dialog` etc) for both `react` and `react-native`.
4
+
5
+ Make your own `showModal` and use it in any component without any `isShow` state or even in a pure function call.
6
+
7
+ ```jsx
8
+ import { ReactNode } from 'react';
9
+ import RootSiblingsManager from 'react-native-root-siblings';
10
+
11
+ export const showModal = (renderModal) => {
12
+ let rootNode;
13
+ const onClose = () => {
14
+ rootNode?.destroy();
15
+ rootNode = null;
16
+ };
17
+ rootNode = new RootSiblingsManager(renderModal(onClose));
18
+ return onClose;
19
+ };
20
+
21
+ import WelcomeModal from './WelcomeModal';
22
+
23
+ export function showWelcomeModal() {
24
+ showModal((onClose) => <WelcomeModal onClose={onClose} />);
25
+ }
26
+
27
+ // ...
28
+ function HomeScreen() {
29
+ return <Button onClick={showWelcomeModal}>Welcome!</Button>
30
+ }
31
+
32
+ setTimeout(showWelcomeModal, 3000);
33
+ ```
34
+
35
+ ---
36
+
37
+
38
+ ## Installation
39
+
40
+ ```sh
41
+ npm i react-native-root-siblings
42
+ ```
43
+
44
+ Insert `RootSiblingParent` between your providers and root app in your root render function.
45
+
46
+ ```jsx
47
+ import { RootSiblingParent } from 'react-native-root-siblings';
48
+
49
+ return (
50
+ <SomeProviders>
51
+ <RootSiblingParent> // <- use RootSiblingParent to wrap your root component
52
+ <App />
53
+ </RootSiblingParent>
54
+ </SomeProviders>
55
+ );
56
+ ```
57
+
58
+ `RootSiblingParent` works as a mounting base and can be mounted multiple times. Only the last mounted one would be active.
59
+
60
+ In react native, a view has a higher hierarchy if it's more close to the root level.
61
+
62
+ ```jsx
63
+ <RootSiblingParent>
64
+ <RootView> // <- the highest view
65
+ <NavigationView>
66
+ <ScreenView> // <- the lowest view
67
+ { /* what if you want to show a fullscreen modal here?
68
+ * usually you have to use a Native Modal which is even higher than RootView
69
+ * but it's buggy and has a lot of limitations
70
+ */}
71
+ <RootSiblingPortal>
72
+ { /* View put in here would be transported to RootSiblingParent
73
+ * So it can have a same hierarchy as the RootView to cover any other views
74
+ */}
75
+ <View>
76
+ </View>
77
+ </RootSiblingPortal>
78
+ </ScreenView>
79
+ </NavigationView>
80
+ </View>
81
+ </RootSiblingParent>
82
+ ```
83
+
84
+ In react we have `createPortal` but still it's not so convenient as it can not be used outside of a component.
85
+
86
+ `react-native-root-siblings` provides the most possible flexibility:
87
+
88
+
89
+
90
+ ## Usage
91
+
92
+ ### Imperative API
93
+
94
+ 1. Create sibling element
95
+
96
+ ```jsx
97
+ let sibling = new RootSiblings(<View
98
+ style={{top: 0,right: 0,bottom: 0,left: 0,backgroundColor: 'red'}}
99
+ />);
100
+ ```
101
+
102
+ This will create a View element cover all of your app elements,
103
+ and returns a sibling instance.
104
+ You can create a sibling anywhere, no matter in a component, hook or even a pure function.
105
+
106
+ 2. Update sibling element
107
+
108
+ ```jsx
109
+ sibling.update(<View
110
+ style={{top: 10,right: 10,bottom: 10,left: 10,backgroundColor: 'blue'}}
111
+ />);
112
+ ```
113
+
114
+ This will update the sibling instance to a View with blue backgroundColor and cover the screen by `10` offset distance.
115
+
116
+ 3. Destroy sibling element
117
+
118
+ ```js
119
+ sibling.destroy();
120
+ ```
121
+
122
+ This will remove the sibling element.
123
+
124
+
125
+ ### Component API
126
+
127
+ ```jsx
128
+ import { RootSiblingPortal } from 'react-native-root-siblings';
129
+
130
+
131
+ class extends Component {
132
+ render() {
133
+ return (
134
+ <RootSiblingPortal>
135
+ <View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(0, 0, 0, 0.25)' }]} />
136
+ </RootSiblingPortal>
137
+ )
138
+ }
139
+ }
140
+
141
+ ```
142
+
143
+ ## EXAMPLE
144
+
145
+ ```jsx
146
+ import React, {
147
+ AppRegistry,
148
+ View,
149
+ Component,
150
+ TouchableHighlight,
151
+ StyleSheet,
152
+ Text
153
+ } from 'react-native';
154
+ import Dimensions from 'Dimensions';
155
+
156
+ // Import library there,it will wrap everything registered by AppRegistry.registerComponent
157
+ // And add or remove other elements after the root component
158
+ import RootSiblings from 'react-native-root-siblings';
159
+
160
+ var id = 0;
161
+ var elements = [];
162
+ class SiblingsExample extends Component{
163
+ addSibling = () => {
164
+ let sibling = new RootSiblings(<View
165
+ style={[styles.sibling, {top: id * 20}]}
166
+ >
167
+ <Text>I`m No.{id}</Text>
168
+ </View>);
169
+ id++;
170
+ elements.push(sibling);
171
+ };
172
+
173
+ destroySibling = () => {
174
+ let lastSibling = elements.pop();
175
+ lastSibling && lastSibling.destroy();
176
+ };
177
+
178
+ updateSibling = () => {
179
+ let lastId = elements.length - 1;
180
+ lastId >= 0 && elements[lastId].update(<View
181
+ style={[styles.sibling, {top: lastId * 20}]}
182
+ >
183
+ <Text>I`m No.{lastId} : {Math.random()}</Text>
184
+ </View>);
185
+ };
186
+
187
+ render() {
188
+ return <View style={styles.container}>
189
+ <TouchableHighlight
190
+ style={styles.button}
191
+ onPress={this.addSibling}
192
+ >
193
+ <Text style={styles.buttonText}>Add element</Text>
194
+ </TouchableHighlight>
195
+ <TouchableHighlight
196
+ style={styles.button}
197
+ onPress={this.destroySibling}
198
+ >
199
+ <Text style={styles.buttonText}>Destroy element</Text>
200
+ </TouchableHighlight>
201
+ <TouchableHighlight
202
+ style={styles.button}
203
+ onPress={this.updateSibling}
204
+ >
205
+ <Text style={styles.buttonText}>Update element</Text>
206
+ </TouchableHighlight>
207
+ </View>;
208
+ }
209
+ }
210
+
211
+ AppRegistry.registerComponent('SiblingsExample', () => SiblingsExample);
212
+
213
+ var styles = StyleSheet.create({
214
+ container: {
215
+ flex: 1,
216
+ alignItems: 'center',
217
+ justifyContent: 'center',
218
+ backgroundColor: 'green',
219
+ },
220
+ button: {
221
+ borderRadius: 4,
222
+ padding: 10,
223
+ marginLeft: 10,
224
+ marginRight: 10,
225
+ backgroundColor: '#ccc',
226
+ borderColor: '#333',
227
+ borderWidth: 1,
228
+ },
229
+ buttonText: {
230
+ color: '#000'
231
+ },
232
+ sibling: {
233
+ left: 0,
234
+ height: 20,
235
+ width: Dimensions.get('window').width / 2,
236
+ backgroundColor: 'blue',
237
+ opacity: 0.5
238
+ }
239
+ });
240
+
241
+ ```
242
+
243
+ ![screen shoot](./Examples/screen-shoot.gif)
244
+
245
+ ## RUN EXAMPLE
246
+
247
+ 1. fork this repository
248
+ 2. change dictionary to `Examples`
249
+ 3. run `npm i`
@@ -0,0 +1,4 @@
1
+ import { ReactNode } from 'react';
2
+ export default function ChildrenWrapper(props: {
3
+ children?: ReactNode;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ export default function ChildrenWrapper(props) {
3
+ return _jsx(_Fragment, { children: props.children });
4
+ }
5
+ //# sourceMappingURL=ChildrenWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChildrenWrapper.js","sourceRoot":"","sources":["../src/ChildrenWrapper.tsx"],"names":[],"mappings":";AAEA,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAA+B;IACrE,OAAO,4BAAG,KAAK,CAAC,QAAQ,GAAI,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from 'react';
2
+ export declare enum RootControllerChanges {
3
+ Insert = 0,
4
+ Update = 1,
5
+ Remove = 2
6
+ }
7
+ export interface RootControllerAction {
8
+ change: RootControllerChanges;
9
+ element: ReactNode;
10
+ updateCallback?: () => void;
11
+ }
12
+ export default class RootController {
13
+ private siblings;
14
+ private pendingActions;
15
+ private callback;
16
+ update(id: string, element: ReactNode, callback?: () => void): void;
17
+ destroy(id: string, callback?: () => void): void;
18
+ setCallback(callback: (id: string, action: RootControllerAction) => void): void;
19
+ private emit;
20
+ }
@@ -0,0 +1,61 @@
1
+ export var RootControllerChanges;
2
+ (function (RootControllerChanges) {
3
+ RootControllerChanges[RootControllerChanges["Insert"] = 0] = "Insert";
4
+ RootControllerChanges[RootControllerChanges["Update"] = 1] = "Update";
5
+ RootControllerChanges[RootControllerChanges["Remove"] = 2] = "Remove";
6
+ })(RootControllerChanges || (RootControllerChanges = {}));
7
+ export default class RootController {
8
+ constructor() {
9
+ this.siblings = new Set();
10
+ this.pendingActions = [];
11
+ this.callback = null;
12
+ }
13
+ update(id, element, callback) {
14
+ if (!this.siblings.has(id)) {
15
+ this.emit(id, {
16
+ change: RootControllerChanges.Insert,
17
+ element,
18
+ updateCallback: callback
19
+ });
20
+ this.siblings.add(id);
21
+ }
22
+ else {
23
+ this.emit(id, {
24
+ change: RootControllerChanges.Update,
25
+ element,
26
+ updateCallback: callback
27
+ });
28
+ }
29
+ }
30
+ destroy(id, callback) {
31
+ if (this.siblings.has(id)) {
32
+ this.emit(id, {
33
+ change: RootControllerChanges.Remove,
34
+ element: null,
35
+ updateCallback: callback
36
+ });
37
+ this.siblings.delete(id);
38
+ }
39
+ else if (callback) {
40
+ callback();
41
+ }
42
+ }
43
+ setCallback(callback) {
44
+ this.callback = callback;
45
+ this.pendingActions.forEach(({ id, action }) => {
46
+ callback(id, action);
47
+ });
48
+ }
49
+ emit(id, action) {
50
+ if (this.callback) {
51
+ this.callback(id, action);
52
+ }
53
+ else {
54
+ this.pendingActions.push({
55
+ action,
56
+ id
57
+ });
58
+ }
59
+ }
60
+ }
61
+ //# sourceMappingURL=RootController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootController.js","sourceRoot":"","sources":["../src/RootController.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,qEAAM,CAAA;IACN,qEAAM,CAAA;IACN,qEAAM,CAAA;AACR,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAQD,MAAM,CAAC,OAAO,OAAO,cAAc;IAAnC;QACU,aAAQ,GAAgB,IAAI,GAAG,EAAE,CAAC;QAClC,mBAAc,GAGjB,EAAE,CAAC;QACA,aAAQ,GAEL,IAAI,CAAC;IAmDlB,CAAC;IAjDQ,MAAM,CAAC,EAAU,EAAE,OAAkB,EAAE,QAAqB;QACjE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACZ,MAAM,EAAE,qBAAqB,CAAC,MAAM;gBACpC,OAAO;gBACP,cAAc,EAAE,QAAQ;aACzB,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACvB;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACZ,MAAM,EAAE,qBAAqB,CAAC,MAAM;gBACpC,OAAO;gBACP,cAAc,EAAE,QAAQ;aACzB,CAAC,CAAC;SACJ;IACH,CAAC;IAEM,OAAO,CAAC,EAAU,EAAE,QAAqB;QAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACzB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACZ,MAAM,EAAE,qBAAqB,CAAC,MAAM;gBACpC,OAAO,EAAE,IAAI;gBACb,cAAc,EAAE,QAAQ;aACzB,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SAC1B;aAAM,IAAI,QAAQ,EAAE;YACnB,QAAQ,EAAE,CAAC;SACZ;IACH,CAAC;IAEM,WAAW,CAChB,QAA4D;QAE5D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,IAAI,CAAC,EAAU,EAAE,MAA4B;QACnD,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;SAC3B;aAAM;YACL,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBACvB,MAAM;gBACN,EAAE;aACH,CAAC,CAAC;SACJ;IACH,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import { Component, ReactNode } from 'react';
2
+ import RootController from './RootController';
3
+ interface RootSiblingsProps {
4
+ controller: RootController;
5
+ renderSibling?: (sibling: ReactNode) => ReactNode;
6
+ children?: ReactNode;
7
+ }
8
+ interface RootSiblingsState {
9
+ siblings: Array<{
10
+ id: string;
11
+ element: ReactNode;
12
+ }>;
13
+ }
14
+ export default class extends Component<RootSiblingsProps, RootSiblingsState> {
15
+ private updatedSiblings;
16
+ private siblingsPool;
17
+ constructor(props: RootSiblingsProps);
18
+ componentDidMount(): void;
19
+ componentDidUpdate(): void;
20
+ render(): import("react/jsx-runtime").JSX.Element;
21
+ private commitChange;
22
+ private invokeCallback;
23
+ private renderSiblings;
24
+ private wrapSibling;
25
+ }
26
+ export {};
@@ -0,0 +1,85 @@
1
+ import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Component } from 'react';
3
+ import StaticContainer from './StaticContainer.js';
4
+ import { RootControllerChanges } from './RootController.js';
5
+ export default class extends Component {
6
+ constructor(props) {
7
+ super(props);
8
+ this.updatedSiblings = new Set();
9
+ this.siblingsPool = [];
10
+ this.state = {
11
+ siblings: []
12
+ };
13
+ }
14
+ componentDidMount() {
15
+ this.props.controller.setCallback((id, change) => {
16
+ setTimeout(() => this.commitChange(id, change));
17
+ });
18
+ }
19
+ componentDidUpdate() {
20
+ this.updatedSiblings.clear();
21
+ }
22
+ render() {
23
+ return (_jsxs(_Fragment, { children: [this.props.children, this.renderSiblings()] }));
24
+ }
25
+ commitChange(id, { change, element, updateCallback }) {
26
+ const siblings = Array.from(this.siblingsPool);
27
+ const index = siblings.findIndex(sibling => sibling.id === id);
28
+ if (change === RootControllerChanges.Remove) {
29
+ if (index > -1) {
30
+ siblings.splice(index, 1);
31
+ }
32
+ else {
33
+ this.invokeCallback(updateCallback);
34
+ return;
35
+ }
36
+ }
37
+ else if (change === RootControllerChanges.Update) {
38
+ if (index > -1) {
39
+ siblings.splice(index, 1, {
40
+ element,
41
+ id
42
+ });
43
+ this.updatedSiblings.add(id);
44
+ }
45
+ else {
46
+ this.invokeCallback(updateCallback);
47
+ return;
48
+ }
49
+ }
50
+ else {
51
+ if (index > -1) {
52
+ siblings.splice(index, 1);
53
+ }
54
+ siblings.push({
55
+ element,
56
+ id
57
+ });
58
+ this.updatedSiblings.add(id);
59
+ }
60
+ this.siblingsPool = siblings;
61
+ this.setState({
62
+ siblings
63
+ }, () => this.invokeCallback(updateCallback));
64
+ }
65
+ invokeCallback(callback) {
66
+ if (callback) {
67
+ callback();
68
+ }
69
+ }
70
+ renderSiblings() {
71
+ return this.state.siblings.map(({ id, element }) => {
72
+ return (_jsx(StaticContainer, { shouldUpdate: this.updatedSiblings.has(id), children: this.wrapSibling(element) }, `root-sibling-${id}`));
73
+ });
74
+ }
75
+ wrapSibling(element) {
76
+ const { renderSibling } = this.props;
77
+ if (renderSibling) {
78
+ return renderSibling(element);
79
+ }
80
+ else {
81
+ return element;
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=RootSiblings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootSiblings.js","sourceRoot":"","sources":["../src/RootSiblings.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ export declare function setSiblingWrapper(wrapper: (sibling: ReactNode) => ReactNode): void;
3
+ export default class RootSiblingsManager {
4
+ private id;
5
+ private manager;
6
+ constructor(element: ReactNode, callback?: () => void);
7
+ update(element: ReactNode, callback?: () => void): void;
8
+ destroy(callback?: () => void): void;
9
+ }
10
+ export declare function RootSiblingParent(props: {
11
+ children: ReactNode;
12
+ inactive?: boolean;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ export declare function RootSiblingPortal(props: {
15
+ children: ReactNode;
16
+ }): null;
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import ChildrenWrapper from './ChildrenWrapper.js';
4
+ import wrapRootComponent from './wrapRootComponent.js';
5
+ let siblingWrapper = sibling => sibling;
6
+ function renderSibling(sibling) {
7
+ return siblingWrapper(sibling);
8
+ }
9
+ export function setSiblingWrapper(wrapper) {
10
+ siblingWrapper = wrapper;
11
+ }
12
+ const { manager: defaultManager } = wrapRootComponent(ChildrenWrapper, renderSibling);
13
+ let uuid = 0;
14
+ const managerStack = [defaultManager];
15
+ const inactiveManagers = new Set();
16
+ function getActiveManager() {
17
+ for (let i = managerStack.length - 1; i >= 0; i--) {
18
+ const manager = managerStack[i];
19
+ if (!inactiveManagers.has(manager)) {
20
+ return manager;
21
+ }
22
+ }
23
+ return defaultManager;
24
+ }
25
+ export default class RootSiblingsManager {
26
+ constructor(element, callback) {
27
+ this.id = `root-sibling-${uuid + 1}`;
28
+ this.manager = getActiveManager();
29
+ this.manager.update(this.id, element, callback);
30
+ uuid++;
31
+ }
32
+ update(element, callback) {
33
+ this.manager.update(this.id, element, callback);
34
+ }
35
+ destroy(callback) {
36
+ this.manager.destroy(this.id, callback);
37
+ }
38
+ }
39
+ export function RootSiblingParent(props) {
40
+ const { inactive } = props;
41
+ const [sibling] = useState(() => {
42
+ const { Root: parentRoot, manager: parentManager } = wrapRootComponent(ChildrenWrapper, renderSibling);
43
+ managerStack.push(parentManager);
44
+ if (inactive) {
45
+ inactiveManagers.add(parentManager);
46
+ }
47
+ return {
48
+ Root: parentRoot,
49
+ manager: parentManager
50
+ };
51
+ });
52
+ useEffect(() => {
53
+ return () => {
54
+ if (sibling) {
55
+ const index = managerStack.indexOf(sibling.manager);
56
+ if (index > 0) {
57
+ managerStack.splice(index, 1);
58
+ }
59
+ }
60
+ };
61
+ }, [sibling]);
62
+ if (inactive && sibling && !inactiveManagers.has(sibling.manager)) {
63
+ inactiveManagers.add(sibling.manager);
64
+ }
65
+ else if (!inactive && sibling && inactiveManagers.has(sibling.manager)) {
66
+ inactiveManagers.delete(sibling.manager);
67
+ }
68
+ const Parent = sibling.Root;
69
+ return _jsx(Parent, { children: props.children });
70
+ }
71
+ export function RootSiblingPortal(props) {
72
+ const [sibling] = useState(() => new RootSiblingsManager(null));
73
+ sibling.update(props.children);
74
+ useEffect(() => {
75
+ if (sibling) {
76
+ return () => sibling.destroy();
77
+ }
78
+ }, [sibling]);
79
+ return null;
80
+ }
81
+ //# sourceMappingURL=RootSiblingsManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootSiblingsManager.js","sourceRoot":"","sources":["../src/RootSiblingsManager.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Component, ReactNode } from 'react';
2
+ interface Props {
3
+ shouldUpdate: boolean;
4
+ children: ReactNode;
5
+ }
6
+ export default class extends Component<Props> {
7
+ shouldComponentUpdate(nextProps: Props): boolean;
8
+ render(): string | number | true | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined;
9
+ }
10
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Component, Children } from 'react';
2
+ export default class extends Component {
3
+ shouldComponentUpdate(nextProps) {
4
+ return nextProps.shouldUpdate;
5
+ }
6
+ render() {
7
+ const child = this.props.children;
8
+ return child === null || child === false ? null : Children.only(child);
9
+ }
10
+ }
11
+ //# sourceMappingURL=StaticContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StaticContainer.js","sourceRoot":"","sources":["../src/StaticContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAa,MAAM,OAAO,CAAC;AAMvD,MAAM,CAAC,OAAO,MAAO,SAAQ,SAAgB;IAC3C,qBAAqB,CAAC,SAAgB;QACpC,OAAO,SAAS,CAAC,YAAY,CAAC;IAChC,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAClC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { ComponentType, PropsWithChildren, ReactNode } from 'react';
2
+ export interface RootSiblingManager {
3
+ update(id: string, element: ReactNode, callback?: () => void): void;
4
+ destroy(id: string, callback?: () => void): void;
5
+ }
6
+ export default function wrapRootComponent<T extends PropsWithChildren>(Root: ComponentType<T>, renderSibling?: (sibling: ReactNode) => ReactNode): {
7
+ Root: ComponentType<T>;
8
+ manager: RootSiblingManager;
9
+ };
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import RootController from './RootController.js';
3
+ import RootSiblings from './RootSiblings.js';
4
+ export default function wrapRootComponent(Root, renderSibling) {
5
+ const controller = new RootController();
6
+ return {
7
+ Root: (props) => {
8
+ return (_jsx(RootSiblings, { controller: controller, renderSibling: renderSibling, children: _jsx(Root, Object.assign({}, props)) }));
9
+ },
10
+ manager: {
11
+ update(id, element, callback) {
12
+ controller.update(id, element, callback);
13
+ },
14
+ destroy(id, callback) {
15
+ controller.destroy(id, callback);
16
+ }
17
+ }
18
+ };
19
+ }
20
+ //# sourceMappingURL=wrapRootComponent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapRootComponent.js","sourceRoot":"","sources":["../src/wrapRootComponent.tsx"],"names":[],"mappings":";AAEA,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAO1C,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,IAAsB,EACtB,aAAiD;IAKjD,MAAM,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;IAExC,OAAO;QACL,IAAI,EAAE,CAAC,KAAQ,EAAE,EAAE;YACjB,OAAO,CACL,KAAC,YAAY,IAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,YAChE,KAAC,IAAI,oBAAK,KAAK,EAAI,GACN,CAChB,CAAC;QACJ,CAAC;QACD,OAAO,EAAE;YACP,MAAM,CAAC,EAAU,EAAE,OAAkB,EAAE,QAAqB;gBAC1D,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,CAAC,EAAU,EAAE,QAAqB;gBACvC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACnC,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "version": "5.0.1-beta.0",
3
+ "name": "@ohos-ports/react-native-root-siblings",
4
+ "type": "module",
5
+ "peerDependencies": {
6
+ "react": ">=17.0.0",
7
+ "react-native": ">=0.60.0"
8
+ },
9
+ "peerDependenciesMeta": {
10
+ "react": {
11
+ "optional": false
12
+ },
13
+ "react-native": {
14
+ "optional": true
15
+ }
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/ohos-ports/ohos-ports.git",
20
+ "directory": "ports/react-native-root-siblings/5.0.1"
21
+ },
22
+ "files": [
23
+ "lib"
24
+ ],
25
+ "license": "MIT",
26
+ "main": "./lib/RootSiblingsManager.js",
27
+ "description": "react native root sibling elements manager",
28
+ "scripts": {
29
+ "lint": "npx tsc --noEmit && npx eslint \"./src/**/*.@(ts|tsx)\" --fix",
30
+ "test": "echo no tests",
31
+ "build": "npx tsc"
32
+ },
33
+ "lint-staged": {
34
+ "./src/**/*.{ts,tsx}": [
35
+ "npm run lint",
36
+ "git add"
37
+ ]
38
+ },
39
+ "devDependencies": {
40
+ "@types/react": "^18.2",
41
+ "@typescript-eslint/eslint-plugin": "^6.7.4",
42
+ "@typescript-eslint/parser": "^6.7.4",
43
+ "eslint": "^8.50.0",
44
+ "eslint-config-prettier": "^9.0.0",
45
+ "eslint-plugin-import": "^2.28.1",
46
+ "eslint-plugin-prettier": "^5.0.0",
47
+ "eslint-plugin-react": "^7.33.2",
48
+ "eslint-plugin-react-hooks": "^4.6.0",
49
+ "eslint-plugin-react-native": "^4.1.0",
50
+ "husky": "^8.0.3",
51
+ "lint-staged": "^14.0.1",
52
+ "prettier": "^3.0.3",
53
+ "typescript": "^5.2.2"
54
+ },
55
+ "keywords": [
56
+ "react-component",
57
+ "react-native",
58
+ "modal",
59
+ "ios",
60
+ "android"
61
+ ],
62
+ "husky": {
63
+ "hooks": {
64
+ "pre-commit": "lint-staged"
65
+ }
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/ohos-ports/ohos-ports/issues"
69
+ }
70
+ }