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

espeakers

v6.2.26

Published

Common code for eSpeakers projects written in React

Downloads

23

Readme

React-es

Codecov npm npm NPM

Library of common React components used on the front-end applications developed for eSpeakers.

When developing on a local machine run this

$ yarn run test

When ready to publish a new version. Use Semantic Versioning to determine the version number. i.e.

$ yarn run prod-patch  #for bug fixes, cleanup or other backwards-compatible changes
$ yarn run prod-minor  #adding new features in a backwards compatable way
$ yarn run prod-major  #breaking changes, including things like updating to a react version that has breaking changes

Installation

To install, use yarn or npm

yarn install espeakers

Then you can use the various components in your projects

import { 
  actions,
  reducers,
  redux,
  components,
  exceptions,
  forms,
  utils 
} from 'espeakers';

or

import { Text } from 'espeakers/forms';
import { Constants } from 'espeakers/utils';
import { Balboa } from 'espeakers/actions';
import { BalboaReducer } from 'espeakers/reducers';
import { AsyncComponent } from 'espeakers/components';

Components

AsyncComponent

Loads the component only when it is requested. Useful when building with modules so the browser doesn't have to load every component/page in a single file.

import { AsyncComponent } from 'espeakers/components';
const AsyncHomePage = AsyncComponent(<HomePage />);

Calendar

Displays the date in a calendar icon. Useful for events and calendar items.

import { Calendar } from 'espeakers/components';
<Calendar date={"2019-01-15"} format={"YYYY-MM-DD"} />

LoadingEllipsis

Displays an animated ellipses, useful when loading content on a page

import { LoadingEllipsis } from 'espeakers/components';
<LoadingEllipsis />

LoadingIndicator

Displays an animated loading circle similar to Google

LoadingIndicator

import { LoadingIndicator } from 'espeakers/components';
<LoadingIndicator />

OauthButtons

Implementation of signon buttons for Google, Facebook, LinkedIn, and Mpi. Used to sign on through Oauth

import { Oauth } from 'espeakers/components';
// Define the callback function that will receive the state from the Oauth service
const callback = (service) => (
  window.location.protocol + "//" + window.location.host + "/oauth-callback/" + service + "/"
);
...
// Render the buttons on the page
<Oauth.Google onSuccess={"/home"} redirect={callback}><div className={"btn btn-danger"}>Google</div></Oauth.Google>
<Oauth.Facebook onSuccess={"/home"} redirect={callback}><div className={"btn btn-primary"}>Facebook</div></Oauth.Facebook>
<Oauth.LinkedIn onSuccess={"/home"} redirect={callback}><div className={"btn btn-warning"}>LinkedIn</div></Oauth.Google>
<Oauth.Mpi onSuccess={"/home"} redirect={callback}><div className={"btn btn-default"}>Mpi</div></Oauth.Google>

PopoverMenu

Displays a menu inside a Bootstrap popover. Very useful to show a form field inside a popover

import { PopoverMenu } from 'espeakers/components';
// Render the buttons on the page
<OverlayTrigger trigger="click" placement="bottom" overlay={
    <PopoverMenu>
        <Dropdown.Item>Item #1</Dropdown.Item>
        <Dropdown.Item>Item #2</Dropdown.Item>
        <Dropdown.Item>Item #3</Dropdown.Item>
    </PopoverMenu>
}>
    <Button>Click me</Button>
</OverlayTrigger>

Exceptions

AuthenticationException

Thrown when a username or password is incorrect

import { AuthenticationException } from 'espeakers/exceptions';
throw new AuthenticationException('Invalid username or password');

AuthorizationException

Thrown when a user does not have access to a resource

import { AuthorizationException } from 'espeakers/exceptions';
throw new AuthorizationException('Not authorized');

SpeakerMissingException

Thrown when a speaker is loaded but they do not exist, or their profile is private, or their profile is not linked to the bureau.
It's recommended to show a 404 page or suggestsions for other speakers if this is thrown.

import { SpeakerMissingException } from 'espeakers/exceptions';
throw new SpeakerMissingException('Speaker not found');

TokenException

Thrown when an api token is invalid or expired. It's recommended to have the user login again or refresh their token.

import { TokenException } from 'espeakers/exceptions';
throw new TokenException('Token expired');

Forms

Many redux-forms components that can be used when building forms

Amount

Displays an amount with a $. Also validates that only numbers are entered

import { Amount } from 'espeakers/forms';
<Field
  name="name"
  component={Amount} 
/>

Checkbox

Displays an chekbox

import { Checkbox } from 'espeakers/forms';
<Field
  name="name"
  component={Checkbox} 
/>

CheckboxDropdown

Displays an list of checkboxes using PopoverMenu

import { CheckboxDropdown } from 'espeakers/forms';
<Field
  name="name"
  component={CheckboxDropdown} 
/>

ColorPicker

Displays a button that opens the system color picker

import { ColorPicker } from 'espeakers/forms';
<Field
  name="name"
  component={ColorPicker} 
/>

DateRangePickerField

Displays an instance of the bootstrap-daterangepicker component

import { DateRangePickerField } from 'espeakers/forms';
<Field
  name="name"
  type={text|button}
  startDate={"01/01/2019"}
  format={"MM/DD/YYYY"}
  component={DateRangePickerField} 
/>

EmailConsent

Displays checkbox agreeing to receive emails

import { EmailConsent } from 'espeakers/forms';
<Field
  name="name"
  component={EmailConsent} 
/>

FileUpoad

Displays file upload control using react-dropzone

import { FileUpoad } from 'espeakers/forms';
<Field
  name="name"
  component={FileUpoad} 
/>

Initials

Displays a textbox for user initials, along with their name and date

import { Initials } from 'espeakers/forms';
<Field
  name="name"
  component={Initials} 
/>

Message

Displays a textarea

import { Message } from 'espeakers/forms';
<Field
  name="name"
  rows={5}
  component={Message} 
/>

OfferAmount

Displays an <Amount /> with $ USD in the input-group-addon

import { OfferAmount } from 'espeakers/forms';
<Field
  name="name"
  component={OfferAmount} 
/>

Password

Displays a password field

import { Password } from 'espeakers/forms';
<Field
  name="name"
  component={Password} 
/>

Phone

Displays a phone nubmer field that automatically formats domestic and international phone numbers

import { Phone } from 'espeakers/forms';
<Field
  name="name"
  component={Phone} 
/>

Radio

Displays a radio button field

import { Radio } from 'espeakers/forms';
<Field
  name="name"
  component={Radio} 
/>

Rating

Displays multiple stars for saving a rating

import { Rating } from 'espeakers/forms';
<Field
    placeholder="Select a rating"
    label="Rate me"
    count={7}
    value={5}
    help_text="Click on a star to rate"
    component={Rating}
    size={"5x"}
    name="rating"
/>

Reason

Displays radio buttons in a group

import { Reason } from 'espeakers/forms';
<Field
  name="color" 
  component={Reason} 
  label="Red" 
/>
<Field 
  name="color"
  component={Reason} 
  label="Green" 
/>
<Field 
  name="color"
  component={Reason}  
  label="Blue" 
/>

SearchSort

Displays a dropdown to select sorting

import { SearchSort } from 'espeakers/forms';
<Field
  name="sort"
  component={SearchSort} 
/>

Selectize

Displays a select component using react-select

import { Selectize } from 'espeakers/forms';
const countries = [
  {label: "United States", value: "US"},
  {label: "Canada", value: "CA"},
  {label: "Mexico", value: "MX"},
];

...

<Field
  name="country"
  component={Selectize} 
  options={countries}
  normalize={(value) => (_.get(value, ["value"], value))}
  format={(value) => ({
    label: _.get(_.keyBy(countries, "value"), [value, "label"], value),
    value: value
  })}
/>

SliderDropdown

Displays a slider within a PopoverMenu

import { SliderDropdown } from 'espeakers/forms';
const marks = {
    0: "Free",
    2: "$1,000",
    5: "$2,500",
    10: "$5,000",
    15: "$7,500",
    20: "$10,000",
    30: "$15,000",
    40: "$20,000",
    50: "$20,000+"
};

...

<Field
  component={SliderDropdown}
  name="budget"
  placeholder="- Any budget -"
  width="medium"
  defaultValue={[10,20]} 
  any_placeholder="Any Budget"
  min={0}
  max={50}
  step={5}
  dots={true}
  marks={marks}
/>

Text

Displays a standard text field

import { Text } from 'espeakers/forms';
<Field
  component={Text}
  name="name"
  label="Name:"
/>

TextWithInputGroup

Displays a standard text field with an input-group-addon before and/or after it

import { TextWithInputGroup } from 'espeakers/forms';
<Field
  component={TextWithInputGroup}
  name="amount"
  label="Amount:"
  input_group_before={<span className="input-group-addon">$</span>}
  input_group_after={<span className="input-group-addon">.00</span>}
/>

Toggle

Displays a toggle for on/off fields using react-toggle

import { Toggle } from 'espeakers/forms';
<Field
  component={Toggle}
  name="option"
  label="Enable:"
/>

ToggleJustified

Displays a toggle for on/off fields using react-toggle to the right

import { ToggleJustified } from 'espeakers/forms';
<Field
  component={ToggleJustified}
  name="option"
  label="Enable:"
  help_text="Click to enable this option"
/>

Username

Displays a username field

import { Username } from 'espeakers/forms';
<Field
  component={Username}
  label="Username:"
/>

Redux Actions

Login.OauthSignin

Used to login to eSpeakers using an Oauth token

import { Oauth } from 'espeakers/actions';
handleSubmit(values, dispatch) {
  // values contains:
  // { 
  //   service: "google|facebook|linkedin|mpi",
  //   access_token|code: "",
  //   state: "buyer[$]1375[$]/home" // user type (buyer, speaker, oauth), bureau, redirect url
  // }
  let state_parts = _.split(_.get(values, ["state"]), "[$]");
  let redir = _.last(state_parts);
  
  if (_.get(values, ["service"]) === "google") {
    return dispatch(Oauth.Google.signin(_.get(values, ["access_token"]), _.join(state_parts, "[$]"), Oauth.Google.getCallbackUrl("google")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "facebook") {
    return dispatch(Oauth.Facebook.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.Facebook.getCallbackUrl("facebook")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "linkedin") {
    return dispatch(Oauth.LinkedIn.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.LinkedIn.getCallbackUrl("linkedin")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "mpi") {
    return dispatch(Oauth.Mpi.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.Mpi.getCallbackUrl("mpi")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
    } else {
      return new Promise((resolve, reject) => {
        return reject("Cannot authenticate without a service");
      });
    }
}

Login.Signin

Used to login to eSpeakers using a username and password

import { Login } from 'espeakers/actions';
handleSubmit(values, dispatch) {
   // values contains:
   // { 
   //   username: "",
   //   password: "",
   //   redir: "/dashboard"
   // }
  return dispatch(Login.Signin(values))
    .catch((err) => {
        throw new SubmissionError({_error: err});
    });
}

Login.TokenSignin

Used to login to eSpeakers using an eSpeakers Authentication token

import { Login } from 'espeakers/actions';
handleSubmit(values, dispatch) {
  // values contains:
  // { 
  //   estoken: "",
  //   redir: "/dashboard"
  // }
  return dispatch(Login.TokenSignin(values))
    .catch((err) => {
        throw new SubmissionError({_error: err});
    });
}

Oauth.Facebook

Used to exchange and Oauth state from Facebook to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.Google

Used to exchange and Oauth state from Google to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.LinkedIn

Used to exchange and Oauth state from LinkedIn to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.Mpi

Used to exchange and Oauth state from Mpi to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Balboa

Thunk used in Redux Actions to send an API Request to the Balboa API on eSpeakers

import { Balboa } from "espeakers/actions";

return function(dispatch, getState) {
  return Balboa(dispatch, getState)
    .get(key, "/record/" + id, {})
    .then((response) => {
      dispatch({
        type: RECORD_GET,
        id: id,
        data: _.get(response, ["data"])
      });
      return response;
    });
}

Rest

Implementation of REST actions within an action. You should extend this object in any Redux Actions

import { Rest, Balboa } from "espeakers/actions";

export const RECORD_GET = 'RECORD_GET';
export const RECORD_GET_ALL = 'RECORD_GET_ALL';
export const RECORD_POST = 'RECORD_POST';
export const RECORD_PUT = 'RECORD_PUT';
export const RECORD_DELETE = 'RECORD_DELETE';

export default _.assign({}, Rest, {
  /**
   * Retrieves a single record.
   * @param id
   * @returns {Function}
   */
  get: function(id) {
    let key = [RECORD_GET];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .get(key, "/record/" + id, {})
          .then((response) => {
            dispatch({
              type: RECORD_GET,
              id: id,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Retrieves all the records.
   * @param params
   * @returns {Function}
   */
  find: function(params) {
    let key = [RECORD_GET_ALL];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .get(key, "/record", params)
          .then((response) => {
            dispatch({
              type: RECORD_GET_ALL,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Inserts a record.  Leave {params.id} 0, otherwise it will be updated
   * @param params
   * @returns {Function}
   */
  add: function(params) {
    let key = [RECORD_POST];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .post(key, "/record", params)
          .then((response) => {
            dispatch({
              type: RECORD_POST,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Updates a record.  Pass in {params.id} to specify the record to update, otherwise it will be added
   * @param params
   * @returns {Function}
   */
  update: function(params) {
    let key = [RECORD_PUT];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .put(key, "/record/" + _.get(params, ["id"]), params)
          .then((response) => {
            dispatch({
              type: RECORD_PUT,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Removes a record.  Pass in {params.id} to specify the record to remove
   * @param params
   * @returns {Function}
   */
  remove: function(id) {
    let key = [RECORD_DELETE];
    return (dispatch, getState) => {
      return self.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .del(key, "/record/" + id, {})
          .then((response) => {
              dispatch({
                type: RECORD_DELETE,
                id: id,
                data: _.get(response, ["data"])
              });
              return response;
          })
      );
    };
  }
});

Redux Reducers

BalboaReducer

Adds the appropriate reducers to the Redux Store to be used by the Balboa Redux Action

import { BalboaReducer } from "espeakers/reducers";

export default combineReducers({
  //...
  // Global App reducers
  balboa3: BalboaReducer,
  //...
});

Utils

Balboa3

Wrapper for fetch that connects to the Balboa API used by eSpeakers

import { Balboa3 } from "espeakers/utils";

const balboa3 = new Balboa3({
  default_params: {
    estoken: token // estoken used for authentication, throws TokenException if invalid
  }
});

...

balboa3.ajax(url, params, method)
  .then((response) => {
    // process response here
  });

Constants

Various site constants used within the system

import { Constants } from 'espeakers/utils';

console.log(Constants);
console.log(Constants.TRUNK_BUREAU_ID);

formatCurrency

Formats the text as USD

import { formatCurrency } from 'espeakers/utils';

console.log(formatCurrency(5)); // $5.00

formatNumber

Formats the text as a number

import { formatNumber } from 'espeakers/utils';

console.log(formatNumber(5)); // 5
console.log(formatNumber(5, 2)); // 5.00
console.log(formatNumber(5.275, 1)); // 5.3
console.log(formatNumber("5", 1)); // 5.0
console.log(formatNumber("abc", 1)); // 0.0

formatPhone

Formats the text as a domestic or international phone number

import { formatPhone } from 'espeakers/utils';

console.log(formatPhone("8005551212")); // (800) 555-1212
console.log(formatPhone("18005551212")); // 1 (800) 555-1212
console.log(formatPhone("1425551212")); // 1425551212
console.log(formatPhone("5551212")); // 555-1212

formatPriceRange

Formats a 2-element array as a price range in the format of $min - $max

import { formatPriceRange } from 'espeakers/utils';

console.log(formatPriceRange([0,1000], "Free")); // Free - $1000
console.log(formatPriceRange([1,1000], "Free")); // $1 - $1000
console.log(formatPriceRange([1000,Infinity], "Free")); // More than $1000