| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import {
- type ReactNode,
- createContext,
- useEffect,
- useRef
- } from "react";
- import {
- type ViewStyle,
- View
- } from "react-native";
- import {
- useKey
- } from "./hooks/useKey";
- import {
- type IManagerHandles,
- Manager
- } from "./Manager";
- import {
- context
- } from "./context";
- interface IHostProps {
- children: ReactNode;
- style?: ViewStyle;
- name?: string;
- }
- export interface IProvider {
- update(key?: string, children?: ReactNode, name?: string): void;
- mount(children: ReactNode, name?: string): string;
- unmount(key?: string): void;
- name?: string;
- }
- export const Context = createContext<IProvider | null>(null);
- export const Host = ({
- children,
- style,
- name
- }: IHostProps): ReactNode => {
- const managerRef = useRef<IManagerHandles>(null);
- const queue: Array<{
- type: "mount" | "update" | "unmount";
- children?: ReactNode;
- name?: string;
- key: string;
- }> = [];
- const {
- generateKey,
- removeKey
- } = useKey();
- useEffect(() => {
- while (queue.length && managerRef.current) {
- const action = queue.pop();
- if (action) {
- switch (action.type) {
- case "mount":
- managerRef.current?.mount(action.key, action.children, action.name);
- break;
- case "update":
- managerRef.current?.update(action.key, action.children, action.name);
- break;
- case "unmount":
- managerRef.current?.unmount(action.key);
- break;
- }
- }
- }
- }, []);
- const mount = (children: ReactNode, _name?: string): string => {
- const key = generateKey();
- const targetName = _name ?? name;
- context.mount(key, children, targetName);
- return key;
- };
- const update = (key: string, children: ReactNode, _name?: string): void => {
- const targetName = _name ?? name;
- context.update(key, children, targetName);
- };
- const unmount = (key: string): void => {
- context.unmount(key);
- removeKey(key);
- };
- return <Context.Provider value={{
- unmount,
- update,
- mount,
- name
- }}>
- <View
- collapsable={false}
- style={[
- {
- pointerEvents: "box-none",
- flex: 1
- },
- style
- ]}
- >
- {children}
- </View>
- <Manager
- ref={managerRef}
- name={name}
- />
- </Context.Provider>;
- };
|