-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a8f530f
commit efee498
Showing
7 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
<h1 align="center">React Aptor</h1> | ||
<p align="center"><img src="./doc/assets/logo.svg" width="450"></p> | ||
<p align="center">React API Connector</p> | ||
|
||
--- | ||
|
||
[آموزش فارسی](./doc/localization/fa.md) | ||
|
||
Most packages are developed separately in javascript or typescript for increasing generality to make them us in all libraries and frameworks. | ||
|
||
Connecting third parties to react is not a routine task. on the other hand, different teams might develop these packages hence development progress can be one step behind the original or terminated at any time. | ||
Also, wrong abstraction or bad design patterns may slow down progress or block it at every new release. | ||
|
||
List of some other concerns: | ||
|
||
- Finding dom nodes by ReactDOM-findDOMNode | ||
- Extensively usage of memoization to improve performance or prevent extra re-renders | ||
- Large size of the project because of duplication and all API definition in react. | ||
- Rely on a global scope (e.g. window) for package internal setting and making it impossible to have more than one instance. | ||
|
||
## react-aptor | ||
|
||
We strived to solve them all at once | ||
|
||
### Small | ||
|
||
The unparsed project size is less than 1 kilobyte (the greatest file is 352 bytes). | ||
|
||
### Manageable | ||
|
||
Your used/defined APIs are entirely under your control. Make it possible to define a slice of APIs which you are surely going to use. | ||
|
||
### React-ish | ||
|
||
Developed with lots of care, try to be zero-anti-pattern in react. | ||
|
||
### Simple | ||
|
||
Simple with a good developer experience. | ||
|
||
### Typescript | ||
|
||
It was developed in typescript and provide the following on the fly: | ||
|
||
- auto-complete | ||
- type-checking | ||
|
||
## How to use | ||
|
||
Connect your react app to any third party in three-step | ||
|
||
1. Define the instantiate function | ||
2. Define the get API function | ||
3. get connected to react by `useAptor` | ||
|
||
--- | ||
|
||
1. **First step** | ||
> Define the instantiate function. | ||
```js | ||
// construct.js | ||
import Something from 'your-third-party' | ||
export default function instantiate(node, params) => | ||
new Something(node, options) | ||
``` | ||
|
||
This function will return an instance of the third-party package. You have access to node (DOM-node) and params. | ||
|
||
> The node is passed by react-aptor as a reference to DOM that is occasionally used as a wrapper for embedding UI. | ||
> Params are optional parameters that are passed by react-aptor and define by you. see the third step. | ||
|
||
2. **Second step** | ||
|
||
> Define the get API function. | ||
|
||
```js | ||
// api.js | ||
export default function getAPI(instance, params) { | ||
return () => ({ | ||
api_key: () => { | ||
/* api defenition */ | ||
}, | ||
}); | ||
} | ||
``` | ||
|
||
react-aptor will pass instance and params to your `getAPI` function. The instance is your third-party instance which has been defined in the first step. | ||
|
||
> Params are optional parameters that are passed by react-aptor and define by you. see the third step. | ||
3. **Third step** | ||
|
||
```jsx | ||
// connector.jsx | ||
import useAptor from "react-aptor"; | ||
import getAPI from "./api"; | ||
import instantiate from "./construct"; | ||
|
||
const Connector = (props, ref) => { | ||
const aptorRef = useAptor(ref, { | ||
getAPI, | ||
instantiate, | ||
/* params: anything */, | ||
}); | ||
|
||
return <div ref={aptorRef} />; | ||
}; | ||
|
||
export default React.forwardRef(Connector); | ||
``` | ||
|
||
For the connection phase, you need to define a `forwardRef` component, grab forwarded-ref and pass that as the first argument of`useAptor` hook. As the configuration argument you need to pass defined `instantiate` (defined in the first step), `getAPI` (defined in the second step), and your custom params argument. The useAptor hook will return you a ref (`aptorRef`) with must be bound to your returned DOM node. | ||
|
||
The params will be then passed to your `instantiate` and `getAPI` function, as you saw in the first and second steps. | ||
The value of params doesn't have any limitation and it can be any arbitrary type (e.g. `undefined`, `number`, `string`, `object`). You have full access to props in your component and you can define params value by props too. | ||
|
||
**Usage Step** | ||
|
||
```jsx | ||
const Main = () => { | ||
const ref = createRef(); | ||
|
||
const apiKeyHandler = () => ref.current?.api_key(); | ||
|
||
return ( | ||
<div> | ||
<Connector ref={ref} /> | ||
<Button onClick={apiKeyHandler}>api call</Button> | ||
</div> | ||
); | ||
}; | ||
``` | ||
Pass `createRef` to the Connector component (made in the third step), and then you can access all of the APIs inside `ref.current` | ||
## Full Typescript support | ||
The project was developed by typescript, see samples for more info. | ||
## **Donation** | ||
🎨 Designer (**BTC**): | ||
`bc1q9fahyct3lrdz47pjf4kfxvsyum2dm74v2hv9xl` | ||
💻 Developer/Maintainer (**BTC**): | ||
`bc1qq8qq63ex7svkkjdjn5axu8angfxytvs83nlujk` | ||
## Samples | ||
### [Quilljs](https://github.com/quilljs/quill) + `typescript` | ||
> Quill is a free, open source WYSIWYG editor built for the modern web. | ||
> <a href="https://codesandbox.io/s/react-aptor--quill-iqwcd"><img src="https://codesandbox.io/static/img/play-codesandbox.svg"></a> | ||
### [FabricJs](http://fabricjs.com/) | ||
> Fabric.js is a powerful and simple. Javascript HTML5 canvas library | ||
> <a href="https://codesandbox.io/s/react-aptor--fabric-hp50c"><img src="https://codesandbox.io/static/img/play-codesandbox.svg"></a> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<div dir="rtl"> | ||
<h1 align="center">React Aptor</h1> | ||
<p align="center"><img src="../assets/logo.svg" width="450"></p> | ||
<p align="center">متصل کننده third-partyهای مستقل به react</p> | ||
|
||
--- | ||
|
||
برخی از پکیجها به صورت کاملا مستقل در javascript یا typescript توسعه داده میشوند تا بتوان از آنها در هر framework یا library دیگری استفاده کرد. | ||
|
||
ارتباط این پکیچها با react کار سادهای نیست (حداقل نه تا قبل از توسعه react-aptor)، از طرفی | ||
توسعه نسخه قابل استفاده در react این پکیجها گاهاً توسط تیم متفاوتی از تیم اصلی توسعه دهندهی third-party صورت میگیرید و این یعنی که توسعه | ||
نسخه react میتوانند یک مرحله عقبتر از نسخه اصلی باشد، یا حتی در مواقغی به صورت کامل متوقف شود. | ||
|
||
از طرفی کم بودن تعداد contributors روی نسخه react، انتخاب ساختار نامناسب و الگوهای بد پیاده سازی ممکن است در اینده پیاده سازی ویژگیهای جدید پکیج اصلی را سخت و یا حتی غیر ممکن کند. | ||
|
||
- استفاده از findDOMNode برای پیدا کردن المانها | ||
- استفاده بسیار زیاد از روشهای memoization برای بهبود زمان لود و جلوگیری از re-render | ||
- حجم زیاد این پروژهها به علت تعریف دوباره اغلب ویژگیهای پکیچ اصلی برای react | ||
- برخی از این پکیجها به صورت global در برنامه تعریف میشوند و توانایی استفاده دو نمونه از آنها در پروژه وجود ندارد. | ||
|
||
## react-aptor | ||
|
||
ما در react-aptor سعی کردیم تمام مشکلات ذکر شده در را رفع کنیم. | ||
|
||
### کوچک | ||
|
||
حجم این پروژه بسیار پایین است. کمتر از ۱ کیلو بایت (۳۵۲ بایت). | ||
|
||
### قابل تغییر | ||
|
||
دسترسی برای تعریف apiهای مورد نیاز کاملا در دست شماست. | ||
|
||
### react-ish | ||
|
||
کلیه پروژه با استاندارهای react نوشته شده و سعی شده هیچ ضد-الگویی (anti-pattern) ای در آن استفاده نشود. | ||
|
||
### ساده | ||
|
||
استفاده از این پیکج بسیار ساده است. | ||
|
||
### Typescript | ||
|
||
پروژه با typescript توسعه داده شده و توانایی استفاده از ویژگیهای زیر را به شما میدهد: | ||
|
||
- auto-complete | ||
- type-checking | ||
|
||
## نحوه استفاده | ||
|
||
برای استفاده از این پکیج شما باید سه عمل زیر را انجام دهید | ||
(برای استاندارد سازی پروژه ما از نامگاری بخصوصی استفاده کردیم.) | ||
|
||
1. پکیج مربوط را instantiate (معرفی) کنید | ||
2. api خود را تعریف کنید. | ||
3. پکیج را به وسیله react-aptor به react متصل کنید. | ||
|
||
## مراحل | ||
|
||
### مرحله اول | ||
|
||
> پکیج مربوط را instantiate (معرفی) بکنید | ||
این تابع باید نمونه پکیجی که استفاده میکنید را به عنوان خروجی باز گرداند. همچنین شما به عنوان ورودیهای که react-aptor در اختیار شما میگذارد به node و پارمترهای تعریف خودتان نیز دسترسی دارید (params). | ||
|
||
> هشدار: ممکن است نیاز به new کرد نباشد، این عمل به عنوان مثال و اینکه پر کاربرد بوده استفاده شده. | ||
<p align="center"><img src="../assets/construct.svg" ></p> | ||
|
||
### مرحله دوم | ||
|
||
> api خود را تعریف کنید. | ||
<p align="center"><img src="../assets/api.svg" ></p> | ||
|
||
برای این منظور شما نیاز به تعریف یک تابع به اسم `getAPI` را دارید. این تابع در حقیقت نقش `api-generator` (تولید کننده api) شما را خواهد داشت. | ||
تابع شما دو ورودیاش را که instance (نمونه پکیجی که استفاده میکنید) و params (تمام تنظیمات مورد نیازی که خودتان تعریف کردهاید) باشند، را در هنگام استفاده از react-aptor دریافت خواهد کرد. | ||
|
||
به عنوان خروحی این تابع باید تابعی را برگردانید (return) کنید که | ||
هیچ ورودی نمیگیرد! اما خروحی این تابع object ای که شامل api های شما به صورت key value هست خواهدبود. | ||
در تعرایف api های خود میتوانید از instance و params به صورت کامل استفاده کنید. | ||
|
||
### مرحله سوم | ||
|
||
> پکیج را به وسیله react-aptor به react متصل کنید. | ||
<p align="center"><img src="../assets/connector.svg"></p> | ||
|
||
برای اتصال api ها به react شما نیاز دارید که یک component | ||
`forwardRef` تعریف کنید و ref به همراه توابع تعریف شده در مرحله ۱ و مرحله ۲ را به react-aptor تحویل بدهید. react-aptor به عنوان خروجی یک node-ref به شما بازمیگرداند که نیاز است آن را به عنوان ref به المان dom ای که تعریف کردهاید متصل کنید. | ||
|
||
### استفاده از api هایی که تعریف شده | ||
|
||
<p align="center"><img src="../assets/usage.svg"></p> | ||
|
||
برای استفاده از api ها در scope (لایه) بالاتر نیاز است از `createRef` در react استفاده کرده و ref را به `Connector` که در مرحله ۳ تعریف کردیم تحویل بدهید. به این ترتیب میتوانید به تمامی api ها از طریق `ref.current` دسترسی یابید. | ||
|
||
## حمایت مالی از | ||
|
||
🎨 طراح (**بیتکوین**): | ||
`bc1q9fahyct3lrdz47pjf4kfxvsyum2dm74v2hv9xl` | ||
|
||
💻 توسعهدهنده (**بیتکوین**): | ||
`bc1qq8qq63ex7svkkjdjn5axu8angfxytvs83nlujk` | ||
|
||
## مثالها | ||
|
||
### `typescript` + [Quilljs](https://github.com/quilljs/quill) | ||
|
||
[مثال نحوه اتصال quilljs به react](https://codesandbox.io/s/react-aptor--quill-iqwcd) | ||
|
||
### [FabricJs](http://fabricjs.com/) | ||
|
||
[مثال نحوه اتصال fabric به react](https://codesandbox.io/s/react-aptor--fabric-hp50c) | ||
|
||
</div> |