Browse Source

refactor: update editor and readme

node 6 years ago
parent
commit
b4c6a13d27
5 changed files with 153 additions and 81 deletions
  1. 113
    66
      README.md
  2. 1
    1
      package.json
  3. 1
    1
      src/components/CommentInput/index.js
  4. 32
    11
      src/components/Editor/index.js
  5. 6
    2
      src/index.js

+ 113
- 66
README.md View File

1
 # Comment
1
 # Comment
2
-通用评论系统
2
+
3
+通用评论系统及编辑器
4
+
5
+`version 0.2.0`
6
+
7
+```js
8
+import Comment, { Editor } from 'comment';
9
+```
10
+
11
+
12
+## Props
13
+
14
+#### Comment
15
+
16
+
17
+| props | type   | default  | required | description |
18
+| ----- | -------| -------- | -------- | ----------- |
19
+| type  | number |          | true     | 评论的 type  |
20
+| businessId | string |     | true     | 评论的 business id|
21
+| API  | string | http://api.links123.net/comment/v1 | false | API 前缀|
22
+| showList | boolean |   true  | false     | 是否显示评论列表|
23
+| showEditor | boolean |   true  | false     | 是否显示评论输入框|
24
+
25
+
26
+##### Editor
27
+
28
+| props | type   | default  | required | description |
29
+| ----- | -------| -------- | -------- | ----------- |
30
+| rows  | number |       5   | false     | 编辑器的高度。默认情况下,回复评论/回复回复的编辑器会比评论的编辑器高度小一行 |
31
+| placeholder | string |  说点什么吧...   | false     | 评论的中的提示文字|
32
+| showEmoji | boolean |   true  | false     | 是否显示 Toolbar 中表情工具|
33
+| showUpload | boolean |   true  | false     | 是否显示 Toolbar 中 上传图片工具|
34
+| value | string |     | false     | 编辑器的值。如果设置了改属性,则编辑器变为受控组件,需要父组件来维护 value|
35
+| onChange | function(value) |     | false     | 编辑器内容改变的回调函数|
36
+| onSubmit | function(value)  |     | false     | 点击提交按钮的回调函数|
37
+| btnSubmitText | string  | 发表    | false     | 提交按钮的文字|
38
+| btnLoading | boolean  | false    | false     | 按钮是否正在加载中|
39
+| btnDisable | boolean  | false    | false     | 按钮是否禁用|
40
+| button | ReactNode  |     | false     | 按钮组件。如果上面几个 btn 相关的属性都无法满足要求,则可以使用 button 来自定义提交编辑器值的按钮|
41
+| emojiToolIcon | ReactNode  |     | false     | Toolbar 中表情的图标 |
42
+| imageToolIcon | ReactNode  |     | false     | Toolbar 中上传文件的图标 |
43
+
44
+### 什么时候不要使用 value/onChange/onSubmit
45
+
46
+如果将 `comment` 作为通用评论组件,则不要使用 `value` `onChange` `onSubmit`。因为组件内部,实现了通用评论的业务逻辑。
47
+
48
+**可以使用 value/onChange/onSubmit 的情况:**
49
+
50
+- 单独使用其中的 `Editor`。即 `import { Editor } from 'comment'`
51
+- 不需要展示评论列表,即设置 `showList: false`
52
+
53
+```jsx
54
+// 单独使用 Editor
55
+<Editor value="xxx" onChange={(v) => console.log(v)} />
56
+
57
+// 不需要展示评论列表
58
+
59
+<Comment type={1}  showList={false}>
60
+  <Editor value="xxx" onChange={(v) => console.log(v)} />
61
+</Comment>
62
+
63
+```
64
+
65
+### button 
66
+
67
+如果使用 `button`,则 `btnLoading` `btnDisable` `btnSubmitText` 都会失效。因为这些属性是针对于编辑器默认的提交按钮设置的。
68
+
69
+所以如果要提交编辑器的值,需要自己在 `Button` 组件上实现提交功能。编辑器的值,可以通过 `onChange` 方法获取到。
70
+
71
+如果使用了 `button` 属性,并且没有为其设置 `onClick` 方法,则 `onClick` 默认为发布评论,即点击按钮会发表评论:
72
+
73
+```jsx
74
+// 如下代码所示
75
+// 点击“自定义按钮”的时候,会发表评论。这是由 Comment 组件内部实现的业务逻辑
76
+<Comment type={1} businessId="test" showList={false}>
77
+  <Editor 
78
+    button={(
79
+      <Button
80
+        type="primary"
81
+        ghost
82
+      >
83
+        自定义按钮
84
+      </Button>
85
+    )}
86
+  />
87
+</Comment>
88
+```
89
+
90
+如果使用了 `button` 属性,并且设置了 `onClick` 方法,则会覆盖默认的 `onClick` 方法:
91
+
92
+```jsx
93
+// 下面的代码,点击的时候,不会提交评论
94
+// 而是会输出 state 的值(
95
+// 即编辑器的值,因为 onChange 将编辑器输入的值通过回调函数传递给了父组件)
96
+<Comment type={1} businessId="test" showList={false}>
97
+  <Editor 
98
+    button={(
99
+      <Button
100
+        type="primary"
101
+        ghost
102
+        value={this.state.value}
103
+        onChange={(value) => this.setState({ value })}
104
+        onClick={() => console.log(this.state.value)}
105
+      >
106
+        自定义按钮
107
+      </Button>
108
+    )}
109
+  />
110
+</Comment>
111
+```
3
 
112
 
4
 
113
 
5
 ## 使用
114
 ## 使用
30
 }
139
 }
31
 ```
140
 ```
32
 
141
 
33
-**注意:最,还需要在 HTML 文件里面引入阿里云 OSS SDK `<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js"></script>`**
142
+**注意:最,还需要在 HTML 文件里面引入阿里云 OSS SDK `<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js"></script>`**
34
 
143
 
35
 
144
 
36
 ### 作为静态文件引入
145
 ### 作为静态文件引入
43
   type: 1,
152
   type: 1,
44
   businessId: "1",
153
   businessId: "1",
45
   API: "http://api.links123.net/comment/v1",
154
   API: "http://api.links123.net/comment/v1",
46
-  showList: false
155
+  showList: true
47
 };
156
 };
48
 
157
 
49
 const editorProps = {
158
 const editorProps = {
93
 </html>
202
 </html>
94
 ```
203
 ```
95
 
204
 
96
-## Props
97
-
98
-#### Comment
99
-
100
-
101
-| props | type   | default  | required | description |
102
-| ----- | -------| -------- | -------- | ----------- |
103
-| type  | number |          | true     | 评论的 type  |
104
-| businessId | string |     | true     | 评论的 business id|
105
-| API  | string | http://api.links123.net/comment/v1 | false | API 前缀|
106
-| showList | boolean |   true  | false     | 是否显示评论列表|
107
-| showEditor | boolean |   true  | false     | 是否显示评论输入框|
108
-
109
-
110
-##### Editor
111
-
112
-| props | type   | default  | required | description |
113
-| ----- | -------| -------- | -------- | ----------- |
114
-| rows  | number |       5   | false     | 编辑器的高度。默认情况下,回复评论/回复回复的编辑器会比评论的编辑器高度小一行 |
115
-| placeholder | string |  说点什么吧...   | false     | 评论的中的提示文字|
116
-| showEmoji | boolean |   true  | false     | 是否显示 Toolbar 中表情工具|
117
-| showUpload | boolean |   true  | false     | 是否显示 Toolbar 中 上传图片工具|
118
-| value | string |     | false     | 编辑器的值。如果设置了改属性,则编辑器变为受控组件,需要父组件来维护 value|
119
-| onChange | function(value) |     | false     | 编辑器内容改变的回调函数|
120
-| onSubmit | function(value)  |     | false     | 点击提交按钮的回调函数|
121
-| btnSubmitText | string  | 发表    | false     | 提交按钮的文字|
122
-| btnLoading | boolean  | false    | false     | 按钮是否正在加载中|
123
-| btnDisable | boolean  | false    | false     | 按钮是否禁用|
124
-| button | ReactNode  |     | false     | 按钮组件。如果上面几个 btn 相关的属性都无法满足要求,则可以使用 button 来自定义提交编辑器值的按钮|
125
-
126
-#### button 
127
-
128
-如果使用 `button`,则 `onSubmit` `btnLoading` `btnDisable` `btnSubmitText` 都会失效。因为这些属性是针对于编辑器默认的提交按钮设置的。
129
-
130
-所以如果要提交编辑器的值,需要自己在 `Button` 组件上实现提交功能。编辑器的值,可以通过 `onChange` 方法获取到。
131
-
132
-
133
-用法示例:
134
-
135
-```jsx
136
-<App type={1} businessId="test">
137
-  <Editor
138
-    // 将编辑器的值保存在 state 中
139
-    onChange={value => this.setState({ value })}
140
-    button={(
141
-      <Button
142
-        onClick={() => console.log(this.state.value)}
143
-      >
144
-      自定义按钮
145
-      </Button>
146
-    )}
147
-  />
148
-</App>
149
-```
150
-
151
 ## 开发
205
 ## 开发
152
 
206
 
153
 ```
207
 ```
158
 ```
212
 ```
159
 
213
 
160
 - `yarn build` 将项目打包成一个单页应用
214
 - `yarn build` 将项目打包成一个单页应用
161
-- `yarn lib` 将项目打包成一个组件
215
+- `yarn lib` 将项目打包成一个 es5 组件
162
 - `yarn prettier` 格式化代码
216
 - `yarn prettier` 格式化代码
163
-
164
-## TODO
165
-
166
-- [ ] 前后端统一错误码
167
-- [x] type 和 businessID 的定义
168
-- [ ] Editor onSubmit 回调
169
-

+ 1
- 1
package.json View File

31
   },
31
   },
32
   "scripts": {
32
   "scripts": {
33
     "precommit": "lint-staged",
33
     "precommit": "lint-staged",
34
-    "prettier": "prettier --trailing-comma --write 'src/**/*.{js,jsx,json,css,less}'",
34
+    "prettier": "prettier --single-quote --trailing-comma --write 'src/**/*.{js,jsx,json,css,less}'",
35
     "start": "react-app-rewired start",
35
     "start": "react-app-rewired start",
36
     "build": "react-app-rewired build",
36
     "build": "react-app-rewired build",
37
     "test": "react-app-rewired test --env=jsdom",
37
     "test": "react-app-rewired test --env=jsdom",

+ 1
- 1
src/components/CommentInput/index.js View File

10
   }
10
   }
11
 
11
 
12
   handleSubmit(value) {
12
   handleSubmit(value) {
13
-    // console.log("handleSubmit comment input value: ", value);
13
+    console.log("handleSubmit comment input value: ", value);
14
     const { action, commentId, replyId, callback } = this.props;
14
     const { action, commentId, replyId, callback } = this.props;
15
     if (action === "comment") {
15
     if (action === "comment") {
16
       this.props.app.sCreateComment({
16
       this.props.app.sCreateComment({

+ 32
- 11
src/components/Editor/index.js View File

111
       btnSubmitText,
111
       btnSubmitText,
112
       btnLoading,
112
       btnLoading,
113
       btnDisabled,
113
       btnDisabled,
114
-      button
114
+      button,
115
+      emojiToolIcon,
116
+      imageToolIcon
115
     } = this.props;
117
     } = this.props;
116
     // console.log("editor: ", this.props);
118
     // console.log("editor: ", this.props);
117
-
119
+    console.log("imageToolIcon: ", imageToolIcon);
120
+    //   var clonedElementWithMoreProps = React.cloneElement(
121
+    //     this.mainContent,
122
+    //     { anotherMessage: "nice to meet ya!" }
123
+    // );
124
+    // console.log('button: ', button);
125
+    console.log("button.props.onClick ", button.props.onClick);
126
+    const handleSubmit = this.handleSubmit;
118
     return (
127
     return (
119
       <div className="editor">
128
       <div className="editor">
120
         <TextArea
129
         <TextArea
138
                 }
147
                 }
139
                 overlayClassName="feed"
148
                 overlayClassName="feed"
140
               >
149
               >
141
-                <Icon type="smile-o" className="icon" />
150
+                {emojiToolIcon || <Icon type="smile-o" className="icon" />}
142
               </Popover>
151
               </Popover>
143
             )}
152
             )}
144
 
153
 
179
                   </div>
188
                   </div>
180
                 }
189
                 }
181
               >
190
               >
182
-                <Icon
183
-                  type="picture"
184
-                  className="icon"
185
-                  style={{ marginLeft: 10 }}
186
-                  onClick={() => this.handleShowUpload(true)}
187
-                />
191
+                {imageToolIcon ? (
192
+                  React.cloneElement(imageToolIcon, {
193
+                    onClick: () => this.handleShowUpload(true)
194
+                  })
195
+                ) : (
196
+                  <Icon
197
+                    type="picture"
198
+                    className="icon"
199
+                    style={{ marginLeft: 10 }}
200
+                    onClick={() => this.handleShowUpload(true)}
201
+                  />
202
+                )}
188
               </Popover>
203
               </Popover>
189
             )}
204
             )}
190
           </div>
205
           </div>
191
 
206
 
192
           <div style={{ float: "right", margin: "5px 11px" }}>
207
           <div style={{ float: "right", margin: "5px 11px" }}>
193
-            {button || (
208
+            {button ? (
209
+              React.cloneElement(button, {
210
+                onClick: button.props.onClick || handleSubmit
211
+              })
212
+            ) : (
194
               <Button
213
               <Button
195
                 onClick={() => this.handleSubmit()}
214
                 onClick={() => this.handleSubmit()}
196
                 type="primary"
215
                 type="primary"
218
   btnSubmitText: PropTypes.string,
237
   btnSubmitText: PropTypes.string,
219
   btnLoading: PropTypes.bool,
238
   btnLoading: PropTypes.bool,
220
   btnDisabled: PropTypes.bool,
239
   btnDisabled: PropTypes.bool,
221
-  button: PropTypes.node
240
+  button: PropTypes.node,
241
+  emojiToolIcon: PropTypes.node,
242
+  imageToolIcon: PropTypes.node
222
 };
243
 };
223
 
244
 
224
 Editor.defaultProps = {
245
 Editor.defaultProps = {

+ 6
- 2
src/index.js View File

1
 import React, { Component } from "react";
1
 import React, { Component } from "react";
2
 import ReactDOM from "react-dom";
2
 import ReactDOM from "react-dom";
3
-import { Button } from "antd";
3
+import { Button, Icon } from "antd";
4
 import App, { Editor } from "./App";
4
 import App, { Editor } from "./App";
5
 import registerServiceWorker from "./registerServiceWorker";
5
 import registerServiceWorker from "./registerServiceWorker";
6
 
6
 
50
         <Button
50
         <Button
51
           type="primary"
51
           type="primary"
52
           ghost
52
           ghost
53
-          onClick={() => console.log("click btn: ", this.state.value)}
53
+          // onClick={() => console.log('click btn: ', this.state.value)}
54
         >
54
         >
55
           自定义按钮
55
           自定义按钮
56
         </Button>
56
         </Button>
57
+      ),
58
+      emojiToolIcon: <Icon type="smile" style={{ fontSize: 23 }} />,
59
+      imageToolIcon: (
60
+        <Icon type="cloud-upload-o" style={{ fontSize: 25, marginLeft: 10 }} />
57
       )
61
       )
58
     };
62
     };
59
 
63