Chigiri 🎗️

Chigiri is a React Context library for calling React Components as data fetchers from async code. It accomplishes this by wrapping components in Promises.

But Why?

You can model a modal/general component as a Promise which resolves with the form contents of that component. This is nice when implementing UI/UX flows like Two Factor Authentication, where blocking until the data is returned, as opposed to hooking into or writing an onSubmit-like function, allows you to maintain variables in execution context. Following this approach, one can trigger components as data fetchers from async code!

Compared to existing packages, Chigiri plays nicely with frameworks like NextJS which rely heavily on Server-side Rendering. This is because existing packages register components at runtime, whereas Chigiri requires you to register all possible modal components at build time using a ComponentTypes-like object.

Limitations

  • triggerPromise lacks inferred typing. You can type triggerPromise by passing a Type Variable
  • ModalProvider can only open 1 modal at a time. Not sure if allowing more than 1 modal open at a time would be an anti-pattern.

Quick Start

Base provider example

Use this provider if you want fine control of the modal component (where it’s rendered in the DOM, props, etc).

import { PromiseProvider, usePromiseWrapper } from 'chigiri';
import ExampleModal from './ExampleModal';

function App() {
  return (
    <PromiseProvider>
      <Child>
    </PromiseProvider>
  )
}

function Child() {
  const { isOpen, resolve, reject, triggerPromise } = usePromiseWrapper();
  const [state, setState] = useState<StateType>();
  const onClick = async () => {
    const stateFromModal = await triggerModal<StateType>();
    setState(stateFromModal);
  }
  return (
    <ExampleModal
      isOpen={isOpen}
      onSubmit={resolve}
      onClose={reject}
    />
    <button onClick={onClick}>Set State</button>
    <h1>State: {state}</h1>
  )
}

Modal provider example

import registerModals from 'chigiri';
import ExampleModal from './ExampleModal';
const modals = {
  ExampleModal: ExampleModal
};
const { useModal, ModalProvider } = registerModals(modals);

function App() {
  return (
    <ModalProvider>
      <Child>
    </ModalProvider>
  )
}

function Child() {
  const { triggerModal } = useModal();
  const [state, setState] = useState<StateType>();
  const onClick = async () => {
    const stateFromModal = await triggerModal<StateType>('ExampleModal', modalProps);
    setState(stateFromModal);
  }
  return (
    <button onClick={onClick}>Set State</button>
    <h1>State: {state}</h1>
  )
}

Maintainers

This library is maintained with ❤️ by me, sigmachirality.

GitHub

View Github