5.0.1 • Published 2 years ago

react-native-root-siblings v5.0.1

Weekly downloads
30,950
License
MIT
Repository
github
Last release
2 years ago

react-native-root-siblings npm version

The easiest way to create overlays(Modal, Popover, Dialog etc) for both react and react-native.

Make your own showModal and use it in any component without any isShow state or even in a pure function call.

import { ReactNode } from 'react';
import RootSiblingsManager from 'react-native-root-siblings';

export const showModal = (renderModal) => {
  let rootNode;
  const onClose = () => {
    rootNode?.destroy();
    rootNode = null;
  };
  rootNode = new RootSiblingsManager(renderModal(onClose));
  return onClose;
};

import WelcomeModal from './WelcomeModal';

export function showWelcomeModal() {
  showModal((onClose) => <WelcomeModal onClose={onClose} />);
}

// ...
function HomeScreen() {
  return <Button onClick={showWelcomeModal}>Welcome!</Button>
}

setTimeout(showWelcomeModal, 3000);

Installation

npm i react-native-root-siblings

Insert RootSiblingParent between your providers and root app in your root render function.

import { RootSiblingParent } from 'react-native-root-siblings';

return (
  <SomeProviders>
    <RootSiblingParent>  // <- use RootSiblingParent to wrap your root component
      <App />
    </RootSiblingParent>
  </SomeProviders>
);      

RootSiblingParent works as a mounting base and can be mounted multiple times. Only the last mounted one would be active.

In react native, a view has a higher hierarchy if it's more close to the root level.

<RootSiblingParent>
  <RootView>  //  <- the highest view
    <NavigationView>
      <ScreenView>  //  <- the lowest view
       { /* what if you want to show a fullscreen modal here?
          * usually you have to use a Native Modal which is even higher than RootView
          * but it's buggy and has a lot of limitations
          */}
        <RootSiblingPortal>
        { /* View put in here would be transported to RootSiblingParent 
            * So it can have a same hierarchy as the RootView to cover any other views
            */}
          <View>
          </View>
        </RootSiblingPortal>
      </ScreenView>
    </NavigationView>
  </View>
</RootSiblingParent>

In react we have createPortal but still it's not so convenient as it can not be used outside of a component.

react-native-root-siblings provides the most possible flexibility:

Usage

Imperative API

  1. Create sibling element
let sibling = new RootSiblings(<View
    style={{top: 0,right: 0,bottom: 0,left: 0,backgroundColor: 'red'}}
/>);

This will create a View element cover all of your app elements, and returns a sibling instance. You can create a sibling anywhere, no matter in a component, hook or even a pure function.

  1. Update sibling element
sibling.update(<View
    style={{top: 10,right: 10,bottom: 10,left: 10,backgroundColor: 'blue'}}
/>);

This will update the sibling instance to a View with blue backgroundColor and cover the screen by 10 offset distance.

  1. Destroy sibling element
sibling.destroy();

This will remove the sibling element.

Component API

import { RootSiblingPortal } from 'react-native-root-siblings';


class extends Component {
    render() {
        return (
            <RootSiblingPortal>
                <View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(0, 0, 0, 0.25)' }]} />
            </RootSiblingPortal>
        )
    }
}

EXAMPLE

import React, {
    AppRegistry,
    View,
    Component,
    TouchableHighlight,
    StyleSheet,
    Text
} from 'react-native';
import Dimensions from 'Dimensions';

// Import library there,it will wrap everything registered by AppRegistry.registerComponent
// And add or remove other elements after the root component
import RootSiblings from 'react-native-root-siblings';

var id = 0;
var elements = [];
class SiblingsExample extends Component{
    addSibling = () => {
        let sibling = new RootSiblings(<View
            style={[styles.sibling, {top: id * 20}]}
        >
            <Text>I`m No.{id}</Text>
        </View>);
        id++;
        elements.push(sibling);
    };

    destroySibling = () => {
        let lastSibling = elements.pop();
        lastSibling && lastSibling.destroy();
    };

    updateSibling = () => {
        let lastId = elements.length - 1;
        lastId >= 0 && elements[lastId].update(<View
            style={[styles.sibling, {top: lastId * 20}]}
        >
            <Text>I`m No.{lastId} : {Math.random()}</Text>
        </View>);
    };

    render() {
        return <View style={styles.container}>
            <TouchableHighlight
                style={styles.button}
                onPress={this.addSibling}
            >
                <Text style={styles.buttonText}>Add element</Text>
            </TouchableHighlight>
            <TouchableHighlight
                style={styles.button}
                onPress={this.destroySibling}
            >
                <Text style={styles.buttonText}>Destroy element</Text>
            </TouchableHighlight>
            <TouchableHighlight
                style={styles.button}
                onPress={this.updateSibling}
            >
                <Text style={styles.buttonText}>Update element</Text>
            </TouchableHighlight>
        </View>;
    }
}

AppRegistry.registerComponent('SiblingsExample', () => SiblingsExample);

var styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'green',
    },
    button: {
        borderRadius: 4,
        padding: 10,
        marginLeft: 10,
        marginRight: 10,
        backgroundColor: '#ccc',
        borderColor: '#333',
        borderWidth: 1,
    },
    buttonText: {
        color: '#000'
    },
    sibling: {
        left: 0,
        height: 20,
        width: Dimensions.get('window').width / 2,
        backgroundColor: 'blue',
        opacity: 0.5
    }
});

screen shoot

RUN EXAMPLE

  1. fork this repository
  2. change dictionary to Examples
  3. run npm i
react-native-sdafreact-native-itablet@miot-plugin/react-native-modals@miot-plugin/react-native-root-tips@tantei/react-native-popup-dialog@tantei/react-native-root-toastyatan8-messagetw-reactnativetemplate@ganeshsinghpapola/rn-toastrn-basic-toastreact-native-custom-components-dwscomic-package@qiscus-integration/react-native-multichannel-widgetreact-native-queue-modal@roto93/react-native-root-toastmomo-component-kitsreact-native-basis-toast@infinitebrahmanuniverse/nolb-react-native-r@everything-registry/sub-chunk-2590taro-rn-plusws-im-react-native@cross2d/react-web-root-toast@cutls/react-native-tiny-toast@dachongziy/react-native-general-actionsheet@cpchain-tools/react-native-root-toast@rtarojs/runtime-rn@rtarojs/taro-rnjs-root-toast@johnnybossboy/template-expotw-reactnativetrc-commontrc-common-develop@arcturis/one-ui@arcturis/react-native-root-loading@arcturis/react-native-root-toast@agreejs/taro-rn@chengdu_ct/react-native-general-actionsheet23mofang-react-native-root-toast@devmaronski/react-native-root-toast@dfeidao/fd-am000002@dfeidao/fd-am000027@dfeidao/fd-am000028@dfeidao/fd-am000029@dfeidao/fd-am000030@dfeidao/fd-am000031@crqlar/expo-sdkyes-framework@ducdh-origin/react-native-modals@dymp/dylphin-rn@gwroger/react-native-root-toast@harrysong/taro-rn@harrysong/runtime-rn@hecom-rn/react-native-full-image-picker@huazhu-fe/react-native-root-toast@iduty/modules@fengweichong/react-native-smart-tip@front-base/rnkits@flyskywhy/react-native-smart-tip@liquid-design/liquid-design-react-native@nmchr7/react-native-snackbar-dialog@fangchan/taro-rn@mifind/taro-rn@miot-plugin/react-native-root-toast@momo-platform/component-kits@john-ui-kit/react-native@jushuitan/react-native-toast@react-native-oh-tpl/react-native-root-modal@qiqi715/react-native-alert@pembajak/react-native-esme-ui-kit@sector-labs/react-native-modalsmy_rn_uiopt-rn-componentsojr-eastspring-sdkreact-native-advanced-toastreact-native-debugtoolsreact-native-debug-menureact-native-dialog-componentreact-native-diaozhao-commonreact-native-common-toastreact-native-custom-viewreact-native-custom-tiny-toastreact-native-easy-ui-kitreact-native-easy-pagereact-native-enhanced-toastreact-native-modals-fixreact-native-model-menusreact-native-little-modalreact-native-mix-toastreact-native-loader-overlayreact-native-loader-overlay-updatedreact-native-form-idablereact-native-help-bubblesreact-native-hs-toastreact-native-iloadingreact-native-formikreact-native-full-image-pickerreact-native-general-actionsheetreact-native-flutterreact-native-flyerreact-native-sdaf-test
5.0.1

2 years ago

5.0.0

2 years ago

4.1.1

4 years ago

4.1.0

5 years ago

4.0.6

6 years ago

4.0.6-0

6 years ago

4.0.5

6 years ago

4.0.4

6 years ago

4.0.3

6 years ago

4.0.2

6 years ago

4.0.1

6 years ago

4.0.1-0

6 years ago

4.0.0

6 years ago

4.0.0-beta.13

6 years ago

4.0.0-beta.12

6 years ago

4.0.0-beta.11

6 years ago

4.0.0-beta.10

6 years ago

4.0.0-beta.9

6 years ago

4.0.0-beta.8

6 years ago

4.0.0-beta.7

6 years ago

4.0.0-beta.6

6 years ago

4.0.0-beta.5

6 years ago

4.0.0-beta.3

6 years ago

4.0.0-beta.2

6 years ago

4.0.0-beta.1

6 years ago

3.2.3

6 years ago

3.2.2

6 years ago

3.2.1

6 years ago

3.1.8

6 years ago

3.2.0

6 years ago

3.1.7

7 years ago

3.1.6

7 years ago

3.1.5

7 years ago

3.1.4

7 years ago

3.1.3

7 years ago

3.1.1

7 years ago

3.1.0

7 years ago

3.0.0

8 years ago

2.2.0

8 years ago

2.1.1

8 years ago

2.1.0

8 years ago

2.0.0

8 years ago

2.0.0-beta2

8 years ago

2.0.0-beta

8 years ago

1.3.0

8 years ago

1.2.1

8 years ago

1.2.0

8 years ago

1.1.3

8 years ago

1.1.2

9 years ago

1.1.1

9 years ago

1.1.0

9 years ago

1.0.8

9 years ago

1.0.7

9 years ago

1.0.6

9 years ago

1.0.5

9 years ago

1.0.4

9 years ago

1.0.3

9 years ago

1.0.2

9 years ago

1.0.1

9 years ago

1.0.0

9 years ago