Manager.tsx 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import {
  2. useImperativeHandle,
  3. type ReactNode,
  4. forwardRef,
  5. useEffect,
  6. useState
  7. } from "react";
  8. import {
  9. StyleSheet,
  10. View
  11. } from "react-native";
  12. import {
  13. context
  14. } from "./context";
  15. export interface IManagerHandles {
  16. update(key?: string, children?: ReactNode, name?: string): void;
  17. mount(key: string, children: ReactNode, name?: string): void;
  18. unmount(key?: string): void;
  19. }
  20. export const Manager = forwardRef(({
  21. name
  22. }: {
  23. name?: string;
  24. }, ref): Array<ReactNode> => {
  25. const [
  26. portals,
  27. setPortals
  28. ] = useState<Array<{
  29. children: ReactNode;
  30. name?: string;
  31. key: string;
  32. }>>([]);
  33. useEffect(() => {
  34. return context.subscribe((newPortals) => {
  35. setPortals(newPortals);
  36. });
  37. }, []);
  38. useImperativeHandle(
  39. ref,
  40. (): IManagerHandles => ({
  41. unmount: context.unmount,
  42. update: context.update,
  43. mount: context.mount
  44. }),
  45. );
  46. return portals
  47. .filter(item => {
  48. if (item.name) {
  49. return item.name === name;
  50. }
  51. return !name;
  52. })
  53. .map((
  54. {
  55. children,
  56. key
  57. },
  58. index: number
  59. ) => (
  60. <View
  61. key={`NCoreUIKit-Portal-${key}-${index}`}
  62. style={[
  63. StyleSheet.absoluteFill,
  64. {
  65. pointerEvents: "box-none"
  66. }
  67. ]}
  68. collapsable={false}
  69. >
  70. {children}
  71. </View>
  72. ));
  73. });