@bearer/react
TypeScript icon, indicating that this package has built-in type declarations

1.13.10 • Public • Published

@bearer/react

Version npm bundle size (scoped) node (scoped) Downloads/week NPM

React tooling for bearer.sh components

Installation

Install dependencies

yarn add @bearer/js @bearer/react

Factory

Factory lets you create components or HOC scoped for an integration. It prevents your to repeat yourself. We recommend creating a file per integration so that it is easier to maintain on the long run (totaly up to you of course)

import { factory, Bearer } from '@bearer/react'
const { Connect, withInvoke } = factory('my-integration-name')

Connect component

This component expect a setupId to authenticate the final user.

import { factory } from '@bearer/react'
const { Connect } = factory('my-integration-name')

class MyComponent extends React.Component {
  handleSuccess = ({ authId }) => {
    // do whatever you want with the authId received
  }
  render() {
    return (
      <Bearer clientId="BEARER_PUBLISHABLE_KEY">
        <Connect
          setupId="setupId"
          render={({ loading, connect, error }) => {
            if (loading) {
              return <Loading />
            }
            if (error) {
              return (
                <div>
                  Error, please retry <button onClick={() => connect()}>Retry</button>
                </div>
              )
            }
            return <button onClick={connect}>Connect ...</button>
          }}
        />
      </Bearer>
    )
  }
}

withInvoke HOC

If for any reasons you want to display data coming bearer but without using built in Web Components, you can easily connect your React application with Bearer servers. More on React HOCs here

Assuming we have a backend function named GimmeData returning an array of string

// myConnectedToBearerComponent.tsx
import { factory } from '@bearer/react'
const { withInvoke } = factory('my-integration-name')

interface TProps {
  loading: boolean
  error?: any
  data?: { title: string }
  invoke: (params: any) => void
  otherDataYouWantToPass: string
}

function DisplayComponent(props: TProps) {
  if (props.loading) {
    return 'Loading'
  }
  if (props.error) {
    return <div>Error: {props.error}</div>
  }
  if (props.data) {
    return <div>Some data passed: {props.data}</div>
  }

  const invoke = () => {
    props.invoke({ query: { authId: 'AUTH_ID' } })
  }

  return (
    <div>
      {props.otherDataYouWantToPass}
      <button onClick={invoke}>Click to invoke</button>
    </div>
  )
}

export default withInvoke('GimmeData')(DisplayComponent)
// if you want to add typing
//export default withInvoke<string[], { otherDataYouWantToPass: string }>('GimmeData')(DisplayComponent)

fromBearer

This component takes html tag name of a component as well as optional type information to produce a react component that can we re-used throughout an application.

import * as React from 'react'
const MyText = fromBearer<{ text?: string; anotherPropery: string }>('bearer-my-text')

class ReactComponent extends React.Component {
  render() {
    return <MyText text="hello" anotherPropery="world" />
  }
}

Output events can be handled by simply adding the eventname as a prop on the component and adding a basic handler

<Share bearer-uuid-feature-shared={this.onShared} />

For these tags to work correctly they must have a parent Bearer

Bearer

This component maintains a shared state for a group of components as well as adding the bearer script tags to the page. This tag can be added at any level of the application as is convenient for the implementation

Example Use

we will use this integration for our examples:

First on the preview page obtain a setup-id from the setup components so we do not need to include these in our page. Next lets define our components in a constants file:

bearer.ts

import { fromBearer } from '@bearer/react'

export const ChannelSelect = fromBearer('bearer-6d29c4-share-slack-beta-4-channel-action')
export const Share = fromBearer<{message?:string, text?:string}>('bearer-6d29c4-share-slack-beta-4-feature-action')
export const SlackConnect = fromBearer('bearer-6d29c4-share-slack-beta-4-connect-action')

We can include the Bearer at any level but in this example lets use it all together in the same component

slack-share-component.tsx

import * as React from 'react'
import { Bearer } from '@bearer/react'
import { SlackConnect, ChannelSelect, Share } from '../../constants/bearer'

export default class SlackShareSetup extends React.Component {
  public render() {
    const intialContext = { 'setup-id': 'SETUP_ID_SAMPLE' }
    return (
      <Bearer clientId="BEARER_PUBLISHABLE_KEY" initialContext={intialContext}>
        <SlackConnect />
        <ChannelSelect />
        <Share message="hello world!" text="Test!" bearer-6d29c4-share-slack-beta-4-feature-shared={this.onShared} />
      </Bearer>
    )
  }
}

This allows to share messages but what if we want to persist the users setup information. @bearer/react provides two methods to acomplish this.

Using onUpdate

Bearer has an onUpdatecallback we can hook into which is called every time data changes within the provider

slack-share-component.tsx

import * as React from 'react'
import { Bearer } from '@bearer/react'
import { SlackConnect, ChannelSelect, Share } from '../../constants/bearer'

export default class SlackShareSetup extends React.Component {
  public render() {
    const intialContext = { 'setup-id': 'SETUP_ID_SAMPLE' }
    return (
      <Bearer
        clientId="BEARER_PUBLISHABLE_KEY"
        initialContext={intialContext}
        onUpdate={(data: any) => {
          this.setState({ data })
        }}
      >
        <SlackConnect />
        <ChannelSelect />
        <Share message="hello world!" text="Test!" bearer-6d29c4-share-slack-beta-4-feature-shared={this.onShared} />
        <button onClick={this.handleSave}>Save Setup</button>
      </Bearer>
    )
  }
  private handleSave = () => console.log('handleSave', this.state.data)
}

using a context consumer

Internally Bearer uses the react context API. For a more advaned but flexable method we can access the consumer directly via BearerContext and then use the currently set details as we wish.

slack-share-component.tsx

import * as React from 'react'
import { Bearer, BearerContext } from '@bearer/react'
import { SlackConnect, ChannelSelect, Share } from '../../constants/bearer'

export default class SlackShareSetup extends React.Component {
  public render() {
    const intialContext = { 'setup-id': 'SETUP_ID_SAMPLE' }
    return (
      <Bearer clientId="BEARER_PUBLISHABLE_KEY" initialContext={intialContext}>
        <SlackConnect />
        <ChannelSelect />
        <Share message="hello world!" text="Test!" bearer-6d29c4-share-slack-beta-4-feature-shared={this.onShared} />
        <BearerContext.Consumer>
          {context => <button onClick={this.handleSave(context.state)}>Save Setup</button>}
        </BearerContext.Consumer>
      </Bearer>
    )
  }
  private handleSave = (data: any) => () => {
    console.log('handleSave', data)
  }
}

Readme

Keywords

Package Sidebar

Install

npm i @bearer/react

Weekly Downloads

8

Version

1.13.10

License

MIT

Unpacked Size

47.7 kB

Total Files

16

Last publish

Collaborators

  • cfabianski
  • qrczeno
  • bearer-engineering-ci-cd
  • gotbadger