npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vcooley/react-inbox-sdk

v0.0.4

Published

A React adapter for InboxSDK

Downloads

6

Readme

React InboxSDK

A React adapter for InboxSDK. This allow you to run your React application directly in Gmail.

This project is in an experimental phase and only supports a subset of the InboxSDK API. The API this library exposes is subject to change with any release.

Usage

See the project in example/ for a fully working example, including configuration that you can use to get your own application started. You probably want to be familiar with the capabilities of the InboxSDK library before using this library.

Basic Example

import InboxSDK from "react-inbox-sdk/InboxSDK";
import { ComposeView, ComposeButton } from "react-inbox-sdk/ComposeView";

function App() {
  return (
    {/* You'll want to include an app id to avoid a warning banner appearing, but you can leave it out for initial development */}
    <InboxSDK appId={process.env.INBOX_SDK_APP_ID}>
      {/* This view will render all of its children for each compose view visible on the page */}
      <ComposeView>
        {/* A button that will be rendered in every compose view */}
        <ComposeButton
          onClick={() => alert("Hello World!")}
        />
      </ComposeView>
    </InboxSDK>
  )
}

Ejecting from the React Wrapper

You can use the hooks exported from the library to "eject" from the React InboxSDK wrapper and use it natively. You can use this feature to use components from the InboxSDK library that aren't exposed by the React wrapper yet.

import { useInboxSDK } from "react-inbox-sdk";
import { ComposeView, useComposeView } from "react-inbox-sdk/ComposeView";

function EjectingComposeButton() {
  const { view: composeView } = useComposeView();
  const inboxSDK = useInboxSDK();

  useEffect(() => {
    let butterBar;
    if (composeView.isReply) {
      butterBar = inboxSDK.ButterBar.showMessage("This is a reply");
      butterBar.on("destroy", () => butterBar = null);
    }
    // Remember to clean up your mess!
    () => {
      butterBar?.destroy();
    }
  }, []);
  
  return null;
}

function App() {
  return (
    <ComposeView>
      <EjectingComposeButton />
    </ComposeView>
  );
}

Ejecting from the React Wrapper

You can use the hooks exported from the library to "eject" from the React InboxSDK wrapper and use it natively. You can use this feature to use components from the InboxSDK library that aren't exposed by the React wrapper yet.

import { useInboxSDK } from "react-inbox-sdk";
import { ComposeView, useComposeView } from "react-inbox-sdk/ComposeView";

function EjectingComposeButton() {
  const { view: composeView } = useComposeView();
  const inboxSDK = useInboxSDK();

  useEffect(() => {
    let butterBar;
    if (composeView.isReply) {
      butterBar = inboxSDK.ButterBar.showMessage("This is a reply");
      butterBar.on("destroy", () => butterBar = null);
    }
    // Remember to clean up your mess!
    () => {
      butterBar?.destroy();
    }
  }, []);
  
  return null;
}

function App() {
  return (
    <ComposeView>
      <EjectingComposeButton />
    </ComposeView>
  );
}

Using Actions exposed by views

function AttachFileComposeButton() {
  const { view: composeView } = useComposeView();
  const inboxSDK = useInboxSDK();
  const attachFile = () => {
    const file = new File(["hello world"], "hello.txt");
    composeView.attachFiles([file]);
  }
  
  return <ComposeButton onClick={attachFile} />;
}

function App() {
  return (
    <ComposeView>
      <EjectingComposeButton />
    </ComposeView>
  );
}

Library Structure

This library implements components for the underlying library that attempt to follow the conventions set there, and are generally set under a root level view component that must wrap the UI components.

For example, in InboxSDK's Compose namespace, the root level view component is called ComposeView (exported from react-inbox-sdk/ComposeView). There are several components that are added via methods starting with "add", addComposeButton, addComposeNotice, and addStatusBar. The corresponding components exported by this library are ComposeButton, ComposeNotice, and StatusBar respectively.

In order to implement actions, such as adding an attachment in the compose view, you can use the hooks to call actions at the appropriate time. For example, useComposeView hook to access the underlying compose view, and then call such as attachFiles that are on the exposed compose view object.

Supported Views

The following InboxSDK views are currently supported in the library, with the names of the related exported components and hooks underneath:

  • [x] InboxSDK
  • InboxSDK, useInboxSDK
  • [ ] Lists
  • [x] Compose
  • ComposeView, useComposeView
    • ComposeButton
    • ComposeNotice
    • StatusBar
  • [x] Conversations
  • ThreadView, useThreadView
    • Label
    • NoticeBar
    • SidebarContentPanel
  • MessageView, useMessageView
    • AttachmentsToolbarButton
    • AttachmentCard
    • ToolbarButton
  • [ ] Toolbars
  • [ ] Router
  • [ ] AppMenu
  • [ ] NavMenu
  • [ ] Widgets
  • [ ] ButterBar
  • [ ] Search
  • [ ] User
  • [ ] Global
  • [ ] Keyboard Shortcuts
  • [ ] Common Data Types

Caveats

  • You may expect this code will only render a button in compose view that is a child of a thread view, such as a reply or forward message compose view.
<InboxSDK appId={'123abc'}>
  <ThreadView>
    <ComposeView>
      <ComposeButton onClick={() => alert("Hello World!")} />
    </ComposeView>
  </ThreadView>
</InboxSDK>

However, this behavior is not currently supported. Instead, this code will render a button even in a new message compose view, but only if a thread is open. In order to accomplish the expected behavior, you can create an intermediate component that checks for the existence of a thread view and renders the button only if the thread view exists.

import { useThreadView } from "react-inbox-sdk/Conversations/ThreadView";

function ThreadOnlyComposeButton() {
  const { view: threadView } = useThreadView();
  if (!threadView) return null;
  return (
    <ComposeButton
      onClick={() => alert("Hello World!")}
    />
  );
}
  • InboxSDK supports modifying the underlying values passed to its view creation components using data streams. This is not currently supported by this adapter. You'll need to unmount and remount on of this library's components to update the underlying SDK's view.