react-powered
v0.0.0-beta
Published
Create an UI with react, consuming an API Rest, really fastly
Downloads
2
Maintainers
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!
:)