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

react-powered

v0.0.0-beta

Published

Create an UI with react, consuming an API Rest, really fastly

Downloads

2

Readme

REACT POWERED

yarn add react-powered

or

npm install react-powered

With react-powered you can make an user interface for any record or data than you needs send. We talking about from create simple contact form to a CRUD fully functional in matter of minutes.

No matter what the REST API 's, react-powered adapts to it.

react-powered uses material-ui by default, to guarantee a clear user interface, but this is completely customizable

In addition to material-ui, react-powered uses react-hook-form with yup resolver, avoiding unnecessary re-renders and facilitating form validation.

Quick example

For this example we use nextjs, but it works perfectly with create-next-app

We are going to make an simple crud of people.

Step 1: Make a layout

import Provider from 'react-powered';

//material-ui (optional)
import myTheme from '...';

const base_uri = 'https://api.example.com/people';
const api_key = '123-YourApiKey';

//this config will applies to all requests of the record
const recordConfig = {
  name: 'people',
  base_uri,
  headers: {
    Autorization: `Bearer ${api_key}`,
    'Content-Type': 'application/json',
  },
};

export default function PeopleLayout({children}) {
  return (
    <Provider config={recordConfig} theme={myTheme}>
      {children}
    </Provider>
  );
}

Step 2: List & delete your records

import PeopleLayout from './PeopleLayout';
import {Reader} from 'react-powered';

/*
dataMap receives the information from the endpoint and return  the
desired structure
*/
const reader = new Reader({dataMap: (data) => data.records});
const ListComponent = reader.list();

export default function PeopleList() {
  return (
    <PeopleLayout>
      <ListComponent
        columns={[
          {
            label: 'Surname',
            dataMap: (item) => item.fields.surname,
          },
          {
            label: 'Actions',
            CustomComponent: (
              {item, destroy}, // Black Magic!
            ) => (
              <button onClick={() => destroy({path: `/${item.id}`})}>
                Delete
              </button>
            ),
          },
        ]}
      />
    </PeopleLayout>
  );
}

This component return a list of people. Easy, true?

Step 3: Create an record with yup rules

import PeopleLayout from './PeopleLayout';
import {Sender} from 'react-powered';
import * as yup from 'yup';

const schema = yup.object().shape({
  name: yup.string().required('The name is required'),
  surname: yup.string().required('The surname is required'),
});

const sender = new Sender({
  dataMap: (data) => ({fields: data}),
});
const FormCompoment = sender.createForm([
  {name: 'name', label: 'Name'},
  {name: 'surname', label: 'Your surname, please'},
]);

export default function PeopleList() {
  return (
    <PeopleLayout>
      <FormCompoment schema={schema} />
    </PeopleLayout>
  );
}

Ready, we create a form with its respective validations;

Step 4: Modify your records

import {Sender} from 'react-powered';
import PeopleLayout from './PeopleLayout';
import * as yup from 'yup';
import {useRouter} from 'next/router';

const schema = yup.object().shape({
  name: yup.string().required('is required'),
});

export default function PeopleUpdate() {
  const router = useRouter();
  const {id} = router.query;

  if (!id) return null;

  const sender = new Sender({
    method: 'put',
    path: `/${id}`,
    dataMap: (data) => ({fields: data}),
    reader: {
      // GET request
      path: `/${id}`,
      dataMap: (data) => data.fields,
    },
  });
  const FormCompoment = sender.createForm([
    {name: 'name', label: 'Name'},
    {name: 'surname'},
  ]);

  return (
    <PeopleLayout>
      <FormCompoment schema={schema} />
    </PeopleLayout>
  );
}

This component creates a form with its respective default values and validates the information with yup

Step 5: Record details

import {useRouter} from 'next/router';
import {Reader} from 'react-powered';
import PeopleLayout from './PeopleLayout';

export default function PeopleShow() {
  const router = useRouter();
  const {id} = router.query;

  if (!id) return null;

  const reader = new Reader({dataMap: (data) => data.fields, path: `/${id}`}); //GET request

  const ShowComponent = reader.show();

  return (
    <PeopleLayout>
      <ShowComponent attributes={[{key: 'name'}, {key: 'surname'}]} />
    </PeopleLayout>
  );
}

FACT: this example is based on the airtable API REST

Settings & customization

Provider component

usage: <Provider config={config} theme={theme}>{children}</Provider>

config properties: | Property | Type | Required | Default value | Observation |---|:---:|:---:|:---:|:---:| | name | String | false/true | undefined | The record name. Is required if you only use the provider for a record | base_uri | String | true | undefined | API REST endpoint | | headers | Object | false | {} | If you applied the headers here they will apply to all requests

Reader class

This class should be used to read information through a GET request, be it for show details of a record or list records

  • usage: new Reader(config)
  • methods:
    • show(): return ShowComponent
    • list(): return ListComponent

config properties:

| Property | Type | Required | Default value | Observation | | -------------- | :--------: | :------: | :---------------------------: | :--------------------------------------: | | path | String | false | "/" | - | | dataMap | function | false | (data) => data | - | | headers | Object | false | {} | It is combined with the provider headers | | onRequestError | function | false | (error) => throw Error(...) | Handles http request error |

ShowComponent properties:

| Property | Type | Required | Default value | Observation/Usage | | --------------- | :---------: | :------: | :-----------: | :-----------------------------------------------------------------------------------------------------------: | | CustomComponent | Component | false | undefined | ({loading, details, destroy}) => <YourComponent /> | | attributes | Array | true | [object] | Here you must define the attributes you want to display, in the order you prefer. | | containerProps | Object | false | {} | These properties will be applied to the container component of ShowComponent: <Box {...containerProps}> ... |

Properties of attributes items:

| Property | Type | Required | Default value | Observation | | -------- | :------: | :------: | :-----------: | :------------------------------------: | | key | String | true | undefined | This key refers to the received object | | label | String | false | undefined | - |

ListComponent properties

| Property | Type | Required | Default value | Observation/Usage | | --------------- | :---------: | :------: | :-----------: | :-----------------------------------------------------------------------------------------------------------: | | CustomComponent | Component | false | undefined | ({loading, records, destroy}) => <YourComponent /> | | columns | Array | true | [object] | Here you must define the columns you want to display, in the order you prefer. | | containerProps | Object | false | {} | These properties will be applied to the container component of ShowComponent: <Box {...containerProps}> ... |

Properties of columns items:

| Property | Type | Required | Default value | Observation/Usage | | --------------- | :---------: | :------: | :-----------: | :-------------------------------------------------------------------------------------------------: | | label | String | false | undefined | - | | dataMap | function | false | undefined | This property can return a string or a function that return a string | | CustomComponent | Component | false | undefined | ({item, destroy})=> <YourComponent> this component is returned (if it exists) before than dataMap |

Property "destroy" on custom components:

Destroy is a function to delete records. It receives a config object as an argument:

| Property | Type | Required | Default value | Observation | | -------------- | :--------: | :------: | :---------------------------: | :--------------------------------------: | | path | String | false | "/" | - | | dataMap | function | false | (data) => data | - | | headers | Object | false | {} | It is combined with the provider headers | | onRequestError | function | false | (error) => throw Error(...) | Handles http request error |

Sender class

This class should be used to send information through a POST, PUT or PATCH request, be it a contact form or create/modify records

  • Usage: new Sender(config)
  • methods:
    • setForm(CustomComponent): return createForm([], CustomComponent)
    • createForm([object, ...], CustomComponent): return FormComponent

config properties:

| Property | Type | Required | Default value | Observation | | -------------- | :--------: | :------: | :---------------------------: | :---------------------------------------------: | | method | String | false | "post" | Can be "post", "put" or "patch" | | path | String | false | "/" | - | | dataMap | function | false | (data) => data | - | | headers | Object | false | {} | It is combined with the provider headers | | onRequestError | function | false | (error) => throw Error(...) | Handles http request error | | reader | object | false | {} | It's equal of config property of Reader class |

CustomComponent (setForm & createForm):

({destroy, loading, details, onSubmit, watch, errors, register}) => (
  <YourComponent />
);
  • details: If you supply the "reader" property inside the "config" object, this property will contain the default values of the record.
  • onSubmit: This function receives the information that you want to send to the endpoint, remember that the information will be processed by dataMap.
  • watch: Wacher of form fields (react-hook-form).
  • errors: Object containing all validation errors by field/name (react-hook-form).
  • register: This property is inherited from react-hook-form and must be used in the "ref" property of the fields to validate and / or submit them. For more information read the react-hook-form documentation.

Properties of fields items (createForms):

| Property | Type | Required | Default value | Observation | | ------------ | :--------------: | :------: | :-----------------------------------: | :---------------------------------------------------------------------: | | type | String | false | "text" | Supported values: "text", "password", "textarea" or "checkbox" | | name | String | true | undefined | The field name | | label | String | false | name property | - | | defaultValue | String/boolean | false | defaultValues[name] (FormComponent) | This props override value of defaultValues property on FormComponent | | rows | Int | false | 4 | For textarea only | | helperText | String | false | error.message | This property is overridden by any error message related with the field |

FormComponent properties:

| Property | Type | Required | Default value | Observation/Usage | | --------------- | :----------: | :------: | :-----------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | HeaderComponent | Component | false | undefined | HeaderComponent={({destroy})=> <YourComponent />} | | FooterComponent | Component | false | Submit button | FooterComponent={({destroy})=> <YourComponent />} | | containerProps | Object | false | {} | These properties will be applied to the container component of ShowComponent: <Box {...containerProps}> ... | | defaultValues | Object | false | {} | {field_name: "value", ...} This property is intended to set default values manually, if you used the "reader" property in the class configurator, this property is not required. | | schema | Yup schema | false | undefined | Here you can set your yup schema, for more information read the yup documentation |

Thanks!

I hope it helps you and allows you to promote the development of your projects!

:)