@karrotframe/plugin
TypeScript icon, indicating that this package has built-in type declarations

0.4.0 • Public • Published

karrotframe plugins extensions

hook interface

interface IScreenInstance {
  id: string
  screenId: string
  nestedRouteCount: number
  present: boolean
  as: string
}

interface Options {
  pop?: (from: string) => void
  push?: (to: string) => void
  replace?: (to: string) => void
  mapperScreenInstance?: (screenInstance: IScreenInstance) => IScreenInstance
}

interface HookParams {
  options?: Options
}

interface BeforePushType extends HookParams {
  to: string
}

interface OnPushedType extends HookParams {
  to: string
}

interface BeforePop extends HookParams {
  from: string
}

interface OnPopped extends HookParams {
  from: string
}

interface OnPoppedWithDataType extends HookParams {
  from: string
  data?: any
}

interface beforeReplace extends HookParams {
  to: string
}

interface onReplaced extends HookParams {
  to: string
}

interface onRegisterScreen extends HookParams {
  screen: {
    id: string
    path: string
    Component: React.ComponentType
  }
}

interface onInsertScreenInstance extends HookParams {
  ptr: number
  screenInstance: {
    id: string
    screenId: string
    present: boolean
    as: string
  }
}

interface onMapScreenInstance extends HookParams {
  ptr: number
}

interface onAddScreenInstancePromise extends HookParams {
  screenInstanceId: string
  screenInstancePromise: {
    resolve: (data: any | null) => void
    onNextPagePopped?: (from: string, data: any) => void
  }
}

interface PluginType {
  lifeCycleHooks: {
    beforePush?: (
      context: BeforePushType,
      next: () => Promise<BeforePushType | void>
    ) => Promise<BeforePushType | void>
    onPushed?: (
      context: OnPushedType,
      next: () => Promise<OnPushedType | void>
    ) => Promise<OnPushedType | void>
    beforePop?: (
      context: BeforePop,
      next: () => Promise<BeforePop | void>
    ) => Promise<BeforePop | void>
    onPopped?: (
      context: OnPopped,
      next: () => Promise<OnPopped | void>
    ) => Promise<OnPopped | void>
    onPoppedWithData?: (
      context: OnPoppedWithDataType,
      next: () => Promise<OnPoppedWithDataType | void>
    ) => Promise<OnPoppedWithDataType | void>
    beforeReplace?: (
      context: beforeReplace,
      next: () => Promise<beforeReplace | void>
    ) => Promise<beforeReplace | void>
    onReplaced?: (
      context: onReplaced,
      next: () => Promise<onReplaced | void>
    ) => Promise<onReplaced | void>
    onRegisterScreen?: (
      context: onRegisterScreen,
      next: () => Promise<onRegisterScreen | void>
    ) => Promise<onRegisterScreen | void>
    onInsertScreenInstance?: (
      context: onInsertScreenInstance,
      next: () => Promise<onInsertScreenInstance | void>
    ) => Promise<onInsertScreenInstance | void>
    onMapScreenInstance?: (
      context: onMapScreenInstance,
      next: () => Promise<onMapScreenInstance | void>
    ) => Promise<onMapScreenInstance | void>
    onAddScreenInstancePromise?: (
      context: onAddScreenInstancePromise,
      next: () => Promise<onAddScreenInstancePromise | void>
    ) => Promise<onAddScreenInstancePromise | void>
  }
}

type NavigatorPluginType = {
  name: string
  provider?: React.FC
  executor: () => PluginType
}

plugin example

import React, { createContext, useContext, useState, useMemo } from 'react'
import type { NavigatorPluginType, PluginType } from '../types/navigator'

export const ContextDataPlugin = createContext<{
  data: any
  setData: (data: any) => void
}>(null as any)

export const DataPluginProvider: React.FC = (props) => {
  const [data, setData] = useState<any>(null)
  return (
    <ContextDataPlugin.Provider value={{ data, setData }}>
      {props.children}
    </ContextDataPlugin.Provider>
  )
}

export const useDataPlugin = (): PluginType & {
  dataFromNextPage: (params: { from: string }) => any
} => {
  const context = useContext(ContextDataPlugin)

  return useMemo(() => {
    return {
      lifeCycleHooks: {
        onPoppedWithData: async ({ from, data }) => {
          context.setData({ [from]: data })
        },
      },
      dataFromNextPage: ({ from }: { from: string }) => context?.data?.[from],
    }
  }, [context])
}

export const dataPlugin: NavigatorPluginType = {
  name: 'dataPlugin',
  provider: DataPluginProvider,
  executor: useDataPlugin,
}
const App: React.FC = () => {
  return (
    <Navigator plugins={[dataPlugin]}>
      <Screen path="/" component={PageHome} />
    </Navigator>
  )
}

composeMiddleware

example

const customMiddlewareFirst = async (
  ctx: BeforePushType,
  next: () => Promise<BeforePushType | void>
): Promise<BeforePushType | void> => {
  await next()
}
const customMiddlewareSecond = async (
  ctx: BeforePushType,
  next: () => Promise<BeforePushType | void>
): Promise<BeforePushType | void> => {
  next()
}
const customMiddlewareThird = async (
  ctx: BeforePushType,
  next: () => Promise<BeforePushType | void>
): Promise<BeforePushType | void> => {
  await next()
}

const middlewareLoggerPlugin: NavigatorPluginType = {
  name: 'middlewareLoggerPlugin',
  executor: () => ({
    lifeCycleHooks: {
      beforePush: composeMiddlewares<BeforePushType>([
        customMiddlewareFirst,
        customMiddlewareSecond,
        customMiddlewareThird,
      ]),
    },
  }),
}

Readme

Keywords

none

Package Sidebar

Install

npm i @karrotframe/plugin

Weekly Downloads

1

Version

0.4.0

License

Apache-2.0

Unpacked Size

49 kB

Total Files

18

Last publish

Collaborators

  • irrationnelle
  • tonyfromundefined