From f18191793be5adfa9b98426433139fe31c3abbd8 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 23 Apr 2017 13:09:52 -0300 Subject: [PATCH] fe plugins --- docs/frontend/PLUGINS.md | 208 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 docs/frontend/PLUGINS.md diff --git a/docs/frontend/PLUGINS.md b/docs/frontend/PLUGINS.md new file mode 100644 index 000000000..94c7b49e9 --- /dev/null +++ b/docs/frontend/PLUGINS.md @@ -0,0 +1,208 @@ +# Plugins +We can build plugins to extend the functionality of Talk. Our plugins are powered by *React*, *Redux* and *GraphQL*. We can also build them with simple vanilla javascript. +The plugins live in the `/plugins` folder. Each plugin must have an `index.js` file and two folders `client` and `server`. + +Our plugin folder structure should look like this: +``` +my-plugin/ + ├── client/ + ├── server/ + └── index.js +``` + + +### The Client Folder +The frontend of our plugin lives inside the `client` folder. The `client` folder must have an `index.js` file that exports the configuration of our plugin. + +``` +my-plugin/ + ├── client/ + │ └── index.js + ├── server/ + └── index.js +``` + +For now our `index.js` file should look like this: + +```js +export default { + // We will add more here later. +}; +``` + + +### Components +We can add our components within the `client` folder. + +``` +my-plugin/ + ├── client/ + │ ├── MyComponent.js + │ └── index.js + ├── server/ + └── index.js +``` + +#### Creating a Component +Our component could look like this: + +```js +import React, {Component} from 'react'; + +class MyButton extends Component { + render() { + return ; + } +} + +export default MyButton; +```` + +We are just creating a component that creates a `button`. Now that we created our component we need to specify where it should get injected within Talk! +To tell Talk where that Component should get injected we need to specify our *Slots*. + +Also, our Component can be a Stateless Component. + +```js +import React from 'react'; +export default = () => ; +```` + +### Slots +In Talk we have defined specific *Slots* where we can inject components. + +Here is how we specify our slots config in `my-plugin/index.js` + +```js +import MyButton from './MyButton'; + +export default { + slots: { + commentDetail: [MyButton] + } +}; +``` + +Here I’m specifying that the MyComponent Component will take place within the `commentDetail` in Talk. + +`commentDetail` it’s a specific slot in the CommentStream. It means that it will be embedded inside de comment detail. + +Slots properties take an`Array` so we can add as many components as we want. + +#### Reducers and Actions : Redux + +Talk is powered by Redux and our plugins can too! Our plugins can have their own reducers and actions. + +```js +import MyButton from './MyButton'; +import reducer from './reducer'; + +export default { + slots: { + commentDetail: [MyButton], + }, + reducer +}; +``` + +### Import Actions from Talk +We can easily trigger `Talk` actions in our plugin Components. + +```js +import React, {Component} from 'react'; +import {connect} from 'react-redux'; +import {bindActionCreators} from 'redux'; +import {addTag, removeTag} from 'coral-plugin-commentbox/actions'; + +class MyButton extends Component { + render() { + return ; + } +} + +const mapStateToProps = ({commentBox}) => ({commentBox}); + +const mapDispatchToProps = dispatch => + bindActionCreators({addTag, removeTag}, dispatch); + +export default connect(mapStateToProps, mapDispatchToProps)(OffTopicCheckbox); +``` + +### Styling our Plugin +Talk uses CSS Modules. This basically means that you can also add your CSS Module to your plugin without colliding with the rest of Talk! + +##### My Component +```js +import styles from './style.css'; + +class MyCoralButton extends Component { + render() { + return ; + } +} +```` + +Our `style.css` should could look like this. +```css + +.button { + background: coral; + border-radius: 3px; +} +``` + +## ESlint and Babel +In talk we use `eslint:recommended` and Babel with the latest ECMAScript Features. But you can use your own! +While building your plugin you need to specify a `.eslintrc.json` file and a`.babelrc` file. + +#### `.eslintrc.json` +```json +{ + "env": { + "browser": true, + "es6": true, + "mocha": true + }, + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + } + }, + "parser": "babel-eslint", + "plugins": [ + "react" + ], + "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "no-console": ["warn", { "allow": ["warn", "error"] }] + } +} +```` + + +#### `. babelrc ` +```json +{ + "presets": [ + "es2015" + ], + "plugins": [ + "add-module-exports", + "transform-class-properties", + "transform-decorators-legacy", + "transform-object-assign", + "transform-object-rest-spread", + "transform-async-to-generator", + "transform-react-jsx" + ] +} +```` + +### The server folder and the index file +Read more about the `/server` and how to extend Talk here. +[talk/PLUGINS.md at master · coralproject/talk · GitHub](https://github.com/coralproject/talk/blob/master/PLUGINS.md) + +