# react-powered

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

Latest version **0.0.0-beta** (published 2021-04-04) · ISC license · 0 weekly downloads

## Install

```sh
npm install react-powered
pnpm add react-powered
yarn add react-powered
bun add react-powered
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.0-beta |
| Published | 2021-04-04 |
| First published | 2021-04-04 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 354.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Alan Toledo |
| Maintainers | alantoledo007 |
| Keywords | react, redux, material-ui, react-hook-forms, yup, CRUD, UI, API, components, customizable |

## Links

- npm: https://www.npmjs.com/package/react-powered
- Repository: https://github.com/alantoledo007/react-powered
- Homepage: https://github.com/alantoledo007/react-powered#readme
- Issues: https://github.com/alantoledo007/react-powered/issues
- npm.io page: https://npm.io/package/react-powered

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.0.0-beta (latest) — 2021-04-04

## 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

```javascript
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

```javascript
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

```javascript
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

```javascript
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

```javascript
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):

```javascript
({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](https://react-hook-form.com/).

### 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](https://github.com/jquense/yup)                                 |

# Thanks!

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

:)

---
_Source: https://npm.io/package/react-powered · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
