amis 1.9.1-beta.0 → 1.9.1-beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (278) hide show
  1. package/lib/RootRenderer.js +10 -2
  2. package/lib/RootRenderer.js.map +2 -2
  3. package/lib/Schema.d.ts +3 -2
  4. package/lib/Schema.js.map +1 -1
  5. package/lib/SchemaRenderer.js +6 -9
  6. package/lib/SchemaRenderer.js.map +2 -2
  7. package/lib/actions/CmptAction.js +4 -4
  8. package/lib/actions/CmptAction.js.map +2 -2
  9. package/lib/components/Button.d.ts +11 -10
  10. package/lib/components/Button.js +2 -2
  11. package/lib/components/Button.js.map +2 -2
  12. package/lib/components/CalendarMobile.d.ts +40 -40
  13. package/lib/components/Checkbox.js +1 -1
  14. package/lib/components/Checkbox.js.map +2 -2
  15. package/lib/components/ContextMenu.d.ts +4 -0
  16. package/lib/components/ContextMenu.js +23 -7
  17. package/lib/components/ContextMenu.js.map +2 -2
  18. package/lib/components/DatePicker.d.ts +40 -40
  19. package/lib/components/DateRangePicker.d.ts +40 -40
  20. package/lib/components/Form.d.ts +22 -0
  21. package/lib/components/Form.js +44 -0
  22. package/lib/components/Form.js.map +13 -0
  23. package/lib/components/FormField.d.ts +65 -0
  24. package/lib/components/FormField.js +48 -0
  25. package/lib/components/FormField.js.map +13 -0
  26. package/lib/components/InputBox.d.ts +10 -10
  27. package/lib/components/InputBox.js +4 -3
  28. package/lib/components/InputBox.js.map +2 -2
  29. package/lib/components/InputBoxWithSuggestion.d.ts +280 -0
  30. package/lib/components/InputBoxWithSuggestion.js +65 -0
  31. package/lib/components/InputBoxWithSuggestion.js.map +13 -0
  32. package/lib/components/ListGroup.d.ts +10 -10
  33. package/lib/components/PickerContainer.d.ts +4 -2
  34. package/lib/components/PickerContainer.js +28 -5
  35. package/lib/components/PickerContainer.js.map +2 -2
  36. package/lib/components/Radios.d.ts +10 -10
  37. package/lib/components/ResultBox.d.ts +40 -40
  38. package/lib/components/Select.d.ts +195 -202
  39. package/lib/components/Select.js +7 -3
  40. package/lib/components/Select.js.map +2 -2
  41. package/lib/components/Textarea.d.ts +568 -2
  42. package/lib/components/Textarea.js +129 -1
  43. package/lib/components/Textarea.js.map +2 -2
  44. package/lib/components/Toast.js +11 -9
  45. package/lib/components/Toast.js.map +2 -2
  46. package/lib/components/UserSelect.d.ts +500 -0
  47. package/lib/components/UserSelect.js +559 -0
  48. package/lib/components/UserSelect.js.map +13 -0
  49. package/lib/components/UserTabSelect.d.ts +320 -0
  50. package/lib/components/UserTabSelect.js +163 -0
  51. package/lib/components/UserTabSelect.js.map +13 -0
  52. package/lib/components/WithRemoteConfig.d.ts +7 -0
  53. package/lib/components/WithRemoteConfig.js +22 -13
  54. package/lib/components/WithRemoteConfig.js.map +2 -2
  55. package/lib/components/calendar/DaysView.d.ts +26 -1
  56. package/lib/components/calendar/DaysView.js +60 -19
  57. package/lib/components/calendar/DaysView.js.map +2 -2
  58. package/lib/components/calendar/TimeView.d.ts +1 -1
  59. package/lib/components/calendar/TimeView.js +10 -3
  60. package/lib/components/calendar/TimeView.js.map +2 -2
  61. package/lib/components/formula/Picker.js +4 -4
  62. package/lib/components/formula/Picker.js.map +2 -2
  63. package/lib/components/icons.d.ts +7 -1
  64. package/lib/components/icons.js +17 -1
  65. package/lib/components/icons.js.map +2 -2
  66. package/lib/components/index.d.ts +2 -1
  67. package/lib/components/index.js +3 -1
  68. package/lib/components/index.js.map +2 -2
  69. package/lib/components/json-schema/Array.d.ts +3 -0
  70. package/lib/components/json-schema/Array.js +125 -0
  71. package/lib/components/json-schema/Array.js.map +13 -0
  72. package/lib/components/json-schema/Item.d.ts +3 -0
  73. package/lib/components/json-schema/Item.js +34 -0
  74. package/lib/components/json-schema/Item.js.map +13 -0
  75. package/lib/components/json-schema/Object.d.ts +3 -0
  76. package/lib/components/json-schema/Object.js +178 -0
  77. package/lib/components/json-schema/Object.js.map +13 -0
  78. package/lib/components/json-schema/index.d.ts +279 -0
  79. package/lib/components/json-schema/index.js +16 -0
  80. package/lib/components/json-schema/index.js.map +13 -0
  81. package/lib/components/schema-editor/Array.js +2 -2
  82. package/lib/components/schema-editor/Array.js.map +2 -2
  83. package/lib/components/schema-editor/Common.d.ts +2 -0
  84. package/lib/components/schema-editor/Common.js +39 -3
  85. package/lib/components/schema-editor/Common.js.map +2 -2
  86. package/lib/components/schema-editor/Object.js +2 -2
  87. package/lib/components/schema-editor/Object.js.map +2 -2
  88. package/lib/components/schema-editor/index.d.ts +45 -41
  89. package/lib/components/schema-editor/index.js +5 -5
  90. package/lib/components/schema-editor/index.js.map +2 -2
  91. package/lib/components/table/ItemActionsWrapper.d.ts +10 -0
  92. package/lib/components/table/ItemActionsWrapper.js +25 -0
  93. package/lib/components/table/ItemActionsWrapper.js.map +13 -0
  94. package/lib/components/table/index.d.ts +48 -41
  95. package/lib/components/table/index.js +46 -18
  96. package/lib/components/table/index.js.map +2 -2
  97. package/lib/helper.css +125 -124
  98. package/lib/helper.css.map +1 -1
  99. package/lib/hooks/use-validation-resolver.d.ts +1 -0
  100. package/lib/hooks/use-validation-resolver.js +49 -0
  101. package/lib/hooks/use-validation-resolver.js.map +13 -0
  102. package/lib/icons/department.js +17 -0
  103. package/lib/icons/menu.js +9 -0
  104. package/lib/icons/post.js +15 -0
  105. package/lib/icons/role.js +14 -0
  106. package/lib/icons/user-remove.js +12 -0
  107. package/lib/index.d.ts +2 -0
  108. package/lib/index.js +3 -1
  109. package/lib/index.js.map +2 -2
  110. package/lib/locale/de-DE.js +11 -1
  111. package/lib/locale/de-DE.js.map +2 -2
  112. package/lib/locale/en-US.js +12 -1
  113. package/lib/locale/en-US.js.map +2 -2
  114. package/lib/locale/zh-CN.js +14 -3
  115. package/lib/locale/zh-CN.js.map +2 -2
  116. package/lib/renderers/Action.js +25 -11
  117. package/lib/renderers/Action.js.map +2 -2
  118. package/lib/renderers/CRUD.js +5 -1
  119. package/lib/renderers/CRUD.js.map +2 -2
  120. package/lib/renderers/Dialog.js +9 -3
  121. package/lib/renderers/Dialog.js.map +2 -2
  122. package/lib/renderers/Drawer.js +5 -1
  123. package/lib/renderers/Drawer.js.map +2 -2
  124. package/lib/renderers/Form/InputDate.d.ts +2 -2
  125. package/lib/renderers/Form/InputDate.js.map +2 -2
  126. package/lib/renderers/Form/JSONSchema.d.ts +23 -0
  127. package/lib/renderers/Form/JSONSchema.js +44 -0
  128. package/lib/renderers/Form/JSONSchema.js.map +13 -0
  129. package/lib/renderers/Form/JSONSchemaEditor.d.ts +2 -3
  130. package/lib/renderers/Form/JSONSchemaEditor.js +9 -24
  131. package/lib/renderers/Form/JSONSchemaEditor.js.map +2 -2
  132. package/lib/renderers/Form/Options.js +11 -5
  133. package/lib/renderers/Form/Options.js.map +2 -2
  134. package/lib/renderers/Form/Textarea.d.ts +1 -8
  135. package/lib/renderers/Form/Textarea.js +11 -75
  136. package/lib/renderers/Form/Textarea.js.map +2 -2
  137. package/lib/renderers/Form/UserSelect.d.ts +54 -0
  138. package/lib/renderers/Form/UserSelect.js +197 -0
  139. package/lib/renderers/Form/UserSelect.js.map +13 -0
  140. package/lib/renderers/Form/index.d.ts +1 -1
  141. package/lib/renderers/Form/index.js +88 -42
  142. package/lib/renderers/Form/index.js.map +2 -2
  143. package/lib/renderers/Form/wrapControl.js.map +2 -2
  144. package/lib/renderers/Log.d.ts +28 -0
  145. package/lib/renderers/Log.js +110 -20
  146. package/lib/renderers/Log.js.map +2 -2
  147. package/lib/renderers/Page.js +5 -1
  148. package/lib/renderers/Page.js.map +2 -2
  149. package/lib/renderers/Service.js +5 -1
  150. package/lib/renderers/Service.js.map +2 -2
  151. package/lib/renderers/Table-v2/index.d.ts +14 -2
  152. package/lib/renderers/Table-v2/index.js +33 -3
  153. package/lib/renderers/Table-v2/index.js.map +2 -2
  154. package/lib/renderers/Wizard.js +37 -14
  155. package/lib/renderers/Wizard.js.map +2 -2
  156. package/lib/store/form.js +65 -45
  157. package/lib/store/form.js.map +2 -2
  158. package/lib/themes/ang-ie11.css +576 -24
  159. package/lib/themes/ang.css +553 -12
  160. package/lib/themes/ang.css.map +1 -1
  161. package/lib/themes/antd-ie11.css +576 -24
  162. package/lib/themes/antd.css +553 -12
  163. package/lib/themes/antd.css.map +1 -1
  164. package/lib/themes/cxd-ie11.css +576 -24
  165. package/lib/themes/cxd.css +553 -12
  166. package/lib/themes/cxd.css.map +1 -1
  167. package/lib/themes/dark-ie11.css +576 -24
  168. package/lib/themes/dark.css +553 -12
  169. package/lib/themes/dark.css.map +1 -1
  170. package/lib/themes/default-ie11.css +576 -24
  171. package/lib/themes/default.css +553 -12
  172. package/lib/themes/default.css.map +1 -1
  173. package/lib/utils/api.js +1 -1
  174. package/lib/utils/api.js.map +2 -2
  175. package/lib/utils/renderer-event.js.map +2 -2
  176. package/package.json +2 -1
  177. package/schema.json +552 -5
  178. package/scss/_properties.scss +20 -8
  179. package/scss/components/_input-box.scss +22 -1
  180. package/scss/components/_json-schema.scss +124 -0
  181. package/scss/components/_log.scss +37 -5
  182. package/scss/components/form/_date-range.scss +1 -0
  183. package/scss/components/form/_select.scss +9 -0
  184. package/scss/components/form/_transfer.scss +19 -3
  185. package/scss/components/form/_user-select.scss +422 -0
  186. package/scss/helper/background/_background-color.scss +125 -124
  187. package/scss/themes/_common.scss +2 -0
  188. package/sdk/ang-ie11.css +670 -24
  189. package/sdk/ang.css +647 -12
  190. package/sdk/antd-ie11.css +670 -24
  191. package/sdk/antd.css +647 -12
  192. package/sdk/barcode.js +51 -51
  193. package/sdk/charts.js +14 -14
  194. package/sdk/codemirror.js +7 -7
  195. package/sdk/color-picker.js +65 -65
  196. package/sdk/cropperjs.js +2 -2
  197. package/sdk/cxd-ie11.css +670 -24
  198. package/sdk/cxd.css +647 -12
  199. package/sdk/dark-ie11.css +670 -24
  200. package/sdk/dark.css +647 -12
  201. package/sdk/exceljs.js +1 -1
  202. package/sdk/helper.css +125 -124
  203. package/sdk/helper.css.map +1 -1
  204. package/sdk/locale/de-DE.js +11 -1
  205. package/sdk/markdown.js +69 -69
  206. package/sdk/papaparse.js +1 -1
  207. package/sdk/renderers/Form/CityDB.js +1 -1
  208. package/sdk/rest.js +16 -16
  209. package/sdk/rich-text.js +62 -62
  210. package/sdk/sdk-ie11.css +670 -24
  211. package/sdk/sdk.css +647 -12
  212. package/sdk/sdk.js +1653 -1637
  213. package/sdk/thirds/hls.js/hls.js +1 -1
  214. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  215. package/sdk/tinymce.js +57 -57
  216. package/src/RootRenderer.tsx +27 -15
  217. package/src/Schema.ts +5 -1
  218. package/src/SchemaRenderer.tsx +1 -4
  219. package/src/actions/CmptAction.ts +4 -4
  220. package/src/components/Button.tsx +3 -0
  221. package/src/components/Checkbox.tsx +2 -1
  222. package/src/components/ContextMenu.tsx +25 -7
  223. package/src/components/Form.tsx +70 -0
  224. package/src/components/FormField.tsx +127 -0
  225. package/src/components/InputBox.tsx +4 -1
  226. package/src/components/InputBoxWithSuggestion.tsx +113 -0
  227. package/src/components/PickerContainer.tsx +20 -5
  228. package/src/components/Select.tsx +18 -10
  229. package/src/components/Textarea.tsx +234 -2
  230. package/src/components/Toast.tsx +19 -18
  231. package/src/components/UserSelect.tsx +850 -0
  232. package/src/components/UserTabSelect.tsx +261 -0
  233. package/src/components/WithRemoteConfig.tsx +35 -11
  234. package/src/components/calendar/DaysView.tsx +117 -49
  235. package/src/components/calendar/TimeView.tsx +11 -6
  236. package/src/components/formula/Picker.tsx +2 -1
  237. package/src/components/icons.tsx +17 -1
  238. package/src/components/index.tsx +3 -1
  239. package/src/components/json-schema/Array.tsx +216 -0
  240. package/src/components/json-schema/Item.tsx +47 -0
  241. package/src/components/json-schema/Object.tsx +339 -0
  242. package/src/components/json-schema/index.tsx +44 -0
  243. package/src/components/schema-editor/Array.tsx +3 -1
  244. package/src/components/schema-editor/Common.tsx +61 -4
  245. package/src/components/schema-editor/Object.tsx +3 -1
  246. package/src/components/schema-editor/index.tsx +12 -5
  247. package/src/components/table/ItemActionsWrapper.tsx +32 -0
  248. package/src/components/table/index.tsx +115 -58
  249. package/src/hooks/use-validation-resolver.ts +45 -0
  250. package/src/icons/department.svg +17 -0
  251. package/src/icons/menu.svg +2 -0
  252. package/src/icons/post.svg +15 -0
  253. package/src/icons/role.svg +14 -0
  254. package/src/icons/user-remove.svg +12 -0
  255. package/src/index.tsx +2 -0
  256. package/src/locale/de-DE.ts +11 -1
  257. package/src/locale/en-US.ts +12 -1
  258. package/src/locale/zh-CN.ts +14 -3
  259. package/src/renderers/Action.tsx +10 -9
  260. package/src/renderers/CRUD.tsx +5 -1
  261. package/src/renderers/Dialog.tsx +9 -3
  262. package/src/renderers/Drawer.tsx +5 -1
  263. package/src/renderers/Form/InputDate.tsx +9 -4
  264. package/src/renderers/Form/JSONSchema.tsx +56 -0
  265. package/src/renderers/Form/JSONSchemaEditor.tsx +8 -27
  266. package/src/renderers/Form/Options.tsx +17 -7
  267. package/src/renderers/Form/Textarea.tsx +7 -117
  268. package/src/renderers/Form/UserSelect.tsx +263 -0
  269. package/src/renderers/Form/index.tsx +28 -18
  270. package/src/renderers/Form/wrapControl.tsx +0 -1
  271. package/src/renderers/Log.tsx +213 -19
  272. package/src/renderers/Page.tsx +6 -1
  273. package/src/renderers/Service.tsx +5 -1
  274. package/src/renderers/Table-v2/index.tsx +65 -2
  275. package/src/renderers/Wizard.tsx +24 -10
  276. package/src/store/form.ts +24 -17
  277. package/src/utils/api.ts +1 -1
  278. package/src/utils/renderer-event.ts +0 -2
@@ -157,20 +157,28 @@ export class RootRenderer extends React.Component<RootRendererProps> {
157
157
  store.setCurrentAction(action);
158
158
  store.openDrawer(ctx);
159
159
  } else if (action.actionType === 'toast') {
160
- action.toast?.items?.forEach((item:any) => {
161
- env.notify(item.level || 'info', item.body ? renderChild('body', item.body, {
162
- ...this.props,
163
- data: ctx
164
- }) : '', {
165
- ...action.toast,
166
- ...item,
167
- title: item.title ? renderChild('title', item.title, {
168
- ...this.props,
169
- data: ctx
170
- }) : null,
171
- useMobileUI: env.useMobileUI
172
- })
173
- })
160
+ action.toast?.items?.forEach((item: any) => {
161
+ env.notify(
162
+ item.level || 'info',
163
+ item.body
164
+ ? renderChild('body', item.body, {
165
+ ...this.props,
166
+ data: ctx
167
+ })
168
+ : '',
169
+ {
170
+ ...action.toast,
171
+ ...item,
172
+ title: item.title
173
+ ? renderChild('title', item.title, {
174
+ ...this.props,
175
+ data: ctx
176
+ })
177
+ : null,
178
+ useMobileUI: env.useMobileUI
179
+ }
180
+ );
181
+ });
174
182
  } else if (action.actionType === 'ajax') {
175
183
  store.setCurrentAction(action);
176
184
  store
@@ -197,7 +205,11 @@ export class RootRenderer extends React.Component<RootRendererProps> {
197
205
  store.data
198
206
  );
199
207
  })
200
- .catch(() => {});
208
+ .catch(e => {
209
+ if (throwErrors || action.countDown) {
210
+ throw e;
211
+ }
212
+ });
201
213
  } else if (
202
214
  action.actionType === 'copy' &&
203
215
  (action.content || action.copy)
package/src/Schema.ts CHANGED
@@ -117,6 +117,7 @@ import {UUIDControlSchema} from './renderers/Form/UUID';
117
117
  import {FormControlSchema} from './renderers/Form/Control';
118
118
  import {TransferPickerControlSchema} from './renderers/Form/TransferPicker';
119
119
  import {TabsTransferPickerControlSchema} from './renderers/Form/TabsTransferPicker';
120
+ import {UserSelectControlSchema} from './renderers/Form/UserSelect';
120
121
  import {JSONSchemaEditorControlSchema} from './renderers/Form/JSONSchemaEditor';
121
122
  import {TableSchemaV2} from './renderers/Table-v2';
122
123
 
@@ -170,6 +171,7 @@ export type SchemaType =
170
171
  | 'static-image' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
171
172
  | 'images'
172
173
  | 'static-images' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
174
+ | 'json-schema'
173
175
  | 'json-schema-editor'
174
176
  | 'json'
175
177
  | 'static-json' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
@@ -334,6 +336,7 @@ export type SchemaType =
334
336
  | 'table-view'
335
337
  | 'portlet'
336
338
  | 'grid-nav'
339
+ | 'users-select'
337
340
  | 'tag'
338
341
 
339
342
  // 原生 input 类型
@@ -465,7 +468,8 @@ export type SchemaObject =
465
468
  | TransferPickerControlSchema
466
469
  | TabsTransferPickerControlSchema
467
470
  | TreeControlSchema
468
- | TreeSelectControlSchema;
471
+ | TreeSelectControlSchema
472
+ | UserSelectControlSchema;
469
473
 
470
474
  export type SchemaCollection =
471
475
  | SchemaObject
@@ -391,13 +391,10 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
391
391
  ref: this.refFn,
392
392
  render: this.renderChild,
393
393
  rootStore: rootStore,
394
+ disabled: disable ?? rest.disabled ?? restSchema.disabled,
394
395
  dispatchEvent: this.dispatchEvent
395
396
  };
396
397
 
397
- if (disable) {
398
- (props as any).disabled = true;
399
- }
400
-
401
398
  // 自动解析变量模式,主要是方便直接引入第三方组件库,无需为了支持变量封装一层
402
399
  if (renderer.autoVar) {
403
400
  for (const key of Object.keys($schema)) {
@@ -56,16 +56,16 @@ export class CmptAction implements RendererAction {
56
56
 
57
57
  // 数据更新
58
58
  if (action.actionType === 'setValue') {
59
- if (component.setData) {
60
- return component.setData(action.args?.value);
59
+ if (component?.setData) {
60
+ return component?.setData(action.args?.value);
61
61
  } else {
62
- return component.props.onChange?.(action.args?.value);
62
+ return component?.props.onChange?.(action.args?.value);
63
63
  }
64
64
  }
65
65
 
66
66
  // 刷新
67
67
  if (action.actionType === 'reload') {
68
- return component.reload?.(undefined, action.args);
68
+ return component?.reload?.(undefined, action.args);
69
69
  }
70
70
 
71
71
  // 执行组件动作
@@ -12,6 +12,7 @@ interface ButtonProps extends React.DOMAttributes<HTMLButtonElement> {
12
12
  id?: string;
13
13
  className?: string;
14
14
  href?: string;
15
+ title?: string;
15
16
  size?: 'xs' | 'sm' | 'md' | 'lg';
16
17
  type: 'button' | 'reset' | 'submit';
17
18
  level: string; // 'link' | 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger' | 'light' | 'dark' | 'default';
@@ -57,6 +58,7 @@ export class Button extends React.Component<ButtonProps> {
57
58
  size,
58
59
  disabled,
59
60
  className,
61
+ title,
60
62
  componentClass: Comp,
61
63
  classnames: cx,
62
64
  children,
@@ -98,6 +100,7 @@ export class Button extends React.Component<ButtonProps> {
98
100
  },
99
101
  className
100
102
  )}
103
+ title={title}
101
104
  disabled={disabled}
102
105
  >
103
106
  {loading && !disabled ? (
@@ -83,7 +83,8 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
83
83
  [`Checkbox--${size}`]: size,
84
84
  'Checkbox--button': optionType === 'button',
85
85
  'Checkbox--button--checked': optionType === 'button' && checked,
86
- 'Checkbox--button--disabled--unchecked': disabled && !checked
86
+ 'Checkbox--button--disabled--unchecked':
87
+ optionType === 'button' && disabled && !checked
87
88
  })}
88
89
  >
89
90
  <input
@@ -70,6 +70,10 @@ export class ContextMenu extends React.Component<
70
70
 
71
71
  menuRef: React.RefObject<HTMLDivElement> = React.createRef();
72
72
  originInstance: this | null;
73
+ prevInfo: { // 记录当前右键位置: 方便下一次做对比
74
+ x: number;
75
+ y: number;
76
+ } | null;
73
77
 
74
78
  constructor(props: ContextMenuProps) {
75
79
  super(props);
@@ -98,13 +102,27 @@ export class ContextMenu extends React.Component<
98
102
  menus: Array<MenuItem>,
99
103
  onClose?: () => void
100
104
  ) {
101
- this.setState({
102
- isOpened: true,
103
- x: info.x,
104
- y: info.y,
105
- menus: menus,
106
- onClose
107
- });
105
+ if (this.state.isOpened) {
106
+ const {x, y} = this.state;
107
+ // 避免 二次触发未进行智能定位 导致遮挡问题
108
+ this.setState({
109
+ x: x + (info.x - (this.prevInfo && this.prevInfo.x ? this.prevInfo.x : 0)),
110
+ y: y + (info.y - (this.prevInfo && this.prevInfo.y ? this.prevInfo.y : 0)),
111
+ menus: menus,
112
+ onClose
113
+ }, () => {
114
+ this.handleEnter(this.menuRef.current as HTMLElement);
115
+ });
116
+ } else {
117
+ this.setState({
118
+ isOpened: true,
119
+ x: info.x,
120
+ y: info.y,
121
+ menus: menus,
122
+ onClose
123
+ });
124
+ }
125
+ this.prevInfo = info;
108
126
  }
109
127
 
110
128
  @autobind
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @file 给组件用的,渲染器里面不要用这个
3
+ */
4
+ import React from 'react';
5
+ import {themeable, ThemeProps} from '../theme';
6
+ import {useForm, UseFormReturn} from 'react-hook-form';
7
+ import {useValidationResolver} from '../hooks/use-validation-resolver';
8
+ import {localeable, LocaleProps} from '../locale';
9
+
10
+ export type FormRef = React.MutableRefObject<
11
+ | {
12
+ submit: () => void;
13
+ }
14
+ | undefined
15
+ >;
16
+
17
+ export interface FormProps extends ThemeProps, LocaleProps {
18
+ defaultValues: any;
19
+ onSubmit: (value: any) => void;
20
+ forwardRef?: FormRef;
21
+ children?: (methods: UseFormReturn) => JSX.Element | null;
22
+ }
23
+
24
+ export function Form(props: FormProps) {
25
+ const {classnames: cx} = props;
26
+ const methods = useForm({
27
+ defaultValues: props.defaultValues,
28
+ resolver: useValidationResolver(props.translate)
29
+ });
30
+
31
+ React.useEffect(() => {
32
+ if (props.forwardRef) {
33
+ // 这个模式别的组件没见到过不知道后续会不会不允许
34
+ props.forwardRef.current = {
35
+ submit: () =>
36
+ new Promise<any>((resolve, reject) => {
37
+ methods.handleSubmit(
38
+ values => resolve(values),
39
+ () => resolve(false)
40
+ )();
41
+ })
42
+ };
43
+ }
44
+
45
+ return () => {
46
+ if (props.forwardRef) {
47
+ props.forwardRef.current = undefined;
48
+ }
49
+ };
50
+ });
51
+
52
+ return (
53
+ <form
54
+ className={cx('Form')}
55
+ onSubmit={methods.handleSubmit(props.onSubmit)}
56
+ noValidate
57
+ >
58
+ {/* 实现回车自动提交 */}
59
+ <input type="submit" style={{display: 'none'}} />
60
+ {props.children?.(methods)}
61
+ </form>
62
+ );
63
+ }
64
+
65
+ const ThemedForm = themeable(localeable(Form));
66
+ type ThemedFormProps = Omit<FormProps, keyof ThemeProps | keyof LocaleProps>;
67
+
68
+ export default React.forwardRef((props: ThemedFormProps, ref: FormRef) => (
69
+ <ThemedForm {...props} forwardRef={ref} />
70
+ ));
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @file 给组件用的,渲染器里面不要用这个
3
+ */
4
+ import React from 'react';
5
+ import {themeable, ThemeProps} from '../theme';
6
+ import {
7
+ ControllerProps as ReactHookFormControllerProps,
8
+ Controller as ReactHookFormController,
9
+ RegisterOptions
10
+ } from 'react-hook-form';
11
+ import {method} from 'lodash';
12
+
13
+ export interface FormFieldProps extends ThemeProps {
14
+ mode?: 'normal' | 'horizontal';
15
+ horizontal?: {
16
+ left?: number;
17
+ right?: number;
18
+ leftFixed?: boolean | number | 'xs' | 'sm' | 'md' | 'lg';
19
+ justify?: boolean; // 两端对齐
20
+ };
21
+ label?: string;
22
+ description?: string;
23
+ isRequired?: boolean;
24
+ hasError?: boolean;
25
+ errors?: string | Array<string>;
26
+ children?: JSX.Element;
27
+ }
28
+
29
+ function FormField(props: FormFieldProps) {
30
+ const {
31
+ mode,
32
+ children,
33
+ classnames: cx,
34
+ className,
35
+ hasError,
36
+ isRequired,
37
+ label,
38
+ description
39
+ } = props;
40
+
41
+ const errors = Array.isArray(props.errors)
42
+ ? props.errors
43
+ : props.errors
44
+ ? [props.errors]
45
+ : [];
46
+
47
+ if (mode === 'horizontal') {
48
+ }
49
+
50
+ return (
51
+ <div
52
+ data-role="form-item"
53
+ className={cx(`Form-item Form-item--normal`, className, {
54
+ 'is-error': hasError,
55
+ [`is-required`]: isRequired
56
+ })}
57
+ >
58
+ {label ? (
59
+ <label className={cx(`Form-label`)}>
60
+ <span>
61
+ {label}
62
+ {isRequired && label ? (
63
+ <span className={cx(`Form-star`)}>*</span>
64
+ ) : null}
65
+ </span>
66
+ </label>
67
+ ) : null}
68
+
69
+ {children}
70
+
71
+ {hasError && errors.length ? (
72
+ <ul className={cx(`Form-feedback`)}>
73
+ {errors.map((msg: string, key: number) => (
74
+ <li key={key}>{msg}</li>
75
+ ))}
76
+ </ul>
77
+ ) : null}
78
+
79
+ {description ? (
80
+ <div className={cx(`Form-description`)}>{description}</div>
81
+ ) : null}
82
+ </div>
83
+ );
84
+ }
85
+
86
+ const ThemedFormField = themeable(FormField);
87
+
88
+ export default ThemedFormField;
89
+
90
+ export interface ControllerProps
91
+ extends ReactHookFormControllerProps,
92
+ Omit<FormFieldProps, keyof ThemeProps> {
93
+ rules?: Omit<
94
+ RegisterOptions,
95
+ 'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'
96
+ > & {
97
+ [propName: string]: any;
98
+ };
99
+ }
100
+ export function Controller(props: ControllerProps) {
101
+ const {render, name, shouldUnregister, defaultValue, control, ...rest} =
102
+ props;
103
+ let rules = {...props.rules};
104
+
105
+ if (rest.isRequired) {
106
+ rules.required = true;
107
+ }
108
+
109
+ return (
110
+ <ReactHookFormController
111
+ name={name}
112
+ rules={rules}
113
+ shouldUnregister={shouldUnregister}
114
+ defaultValue={defaultValue}
115
+ control={control}
116
+ render={methods => (
117
+ <ThemedFormField
118
+ {...rest}
119
+ hasError={!!methods.fieldState.error}
120
+ errors={methods.fieldState.error?.message}
121
+ >
122
+ {render(methods)}
123
+ </ThemedFormField>
124
+ )}
125
+ />
126
+ );
127
+ }
@@ -37,6 +37,7 @@ export class InputBox extends React.Component<InputBoxProps, InputBoxState> {
37
37
  @autobind
38
38
  clearValue(e: any) {
39
39
  e.preventDefault();
40
+ e.stopPropagation();
40
41
 
41
42
  const onClear = this.props.onClear;
42
43
  const onChange = this.props.onChange;
@@ -81,6 +82,7 @@ export class InputBox extends React.Component<InputBoxProps, InputBoxState> {
81
82
  prefix: result,
82
83
  children,
83
84
  borderMode,
85
+ onClick,
84
86
  ...rest
85
87
  } = this.props;
86
88
  const isFocused = this.state.isFocused;
@@ -91,9 +93,10 @@ export class InputBox extends React.Component<InputBoxProps, InputBoxState> {
91
93
  'is-focused': isFocused,
92
94
  'is-disabled': disabled,
93
95
  'is-error': hasError,
94
- 'is-clickable': rest.onClick,
96
+ 'is-clickable': onClick,
95
97
  [`InputBox--border${ucFirst(borderMode)}`]: borderMode
96
98
  })}
99
+ onClick={onClick}
97
100
  >
98
101
  {result}
99
102
 
@@ -0,0 +1,113 @@
1
+ import React from 'react';
2
+ import {findDOMNode} from 'react-dom';
3
+ import {localeable, LocaleProps} from '../locale';
4
+ import {themeable, ThemeProps} from '../theme';
5
+ // @ts-ignore
6
+ import {matchSorter} from 'match-sorter';
7
+ import PopOverContainer from './PopOverContainer';
8
+ import SearchBox from './SearchBox';
9
+ import ListSelection from './GroupedSelection';
10
+ import InputBox from './InputBox';
11
+ import {Icon} from './icons';
12
+
13
+ export interface InputBoxWithSuggestionProps extends ThemeProps, LocaleProps {
14
+ options: Array<any>;
15
+ value: any;
16
+ onChange: (value: any) => void;
17
+ disabled?: boolean;
18
+ searchable?: boolean;
19
+ popOverContainer?: any;
20
+ hasError?: boolean;
21
+ placeholder?: string;
22
+ clearable?: boolean;
23
+ }
24
+
25
+ const option2value = (item: any) => item.value;
26
+
27
+ export class InputBoxWithSuggestion extends React.Component<InputBoxWithSuggestionProps> {
28
+ constructor(props: InputBoxWithSuggestionProps) {
29
+ super(props);
30
+ this.state = {
31
+ searchText: ''
32
+ };
33
+ this.onSearch = this.onSearch.bind(this);
34
+ this.filterOptions = this.filterOptions.bind(this);
35
+ }
36
+
37
+ onSearch(text: string) {
38
+ let txt = text.toLowerCase();
39
+
40
+ this.setState({searchText: txt});
41
+ }
42
+
43
+ filterOptions(options: any[]) {
44
+ return matchSorter(options, this.props.value, {
45
+ keys: ['label', 'value']
46
+ });
47
+ }
48
+
49
+ // 选了值,还原options
50
+ onPopClose(e: React.MouseEvent, onClose: () => void) {
51
+ this.setState({searchText: ''});
52
+ onClose();
53
+ }
54
+
55
+ render() {
56
+ const {
57
+ placeholder,
58
+ onChange,
59
+ value,
60
+ classnames: cx,
61
+ disabled,
62
+ translate: __,
63
+ searchable,
64
+ popOverContainer,
65
+ clearable,
66
+ hasError
67
+ } = this.props;
68
+ const options = this.filterOptions(this.props.options);
69
+
70
+ return (
71
+ <PopOverContainer
72
+ popOverContainer={popOverContainer || (() => findDOMNode(this))}
73
+ popOverRender={({onClose}) => (
74
+ <>
75
+ {searchable ? (
76
+ <SearchBox mini={false} onSearch={this.onSearch} />
77
+ ) : null}
78
+ <ListSelection
79
+ multiple={false}
80
+ onClick={e => this.onPopClose(e, onClose)}
81
+ options={options}
82
+ value={[value]}
83
+ option2value={option2value}
84
+ onChange={(value: any) => {
85
+ onChange?.(value);
86
+ }}
87
+ />
88
+ </>
89
+ )}
90
+ >
91
+ {({onClick, ref, isOpened}) => (
92
+ <InputBox
93
+ className={cx('InputBox--sug', isOpened ? 'is-active' : '')}
94
+ ref={ref}
95
+ placeholder={placeholder}
96
+ disabled={disabled}
97
+ value={options.find(o => o.value === value)?.label ?? value}
98
+ onChange={onChange}
99
+ clearable={clearable}
100
+ onClick={onClick}
101
+ hasError={hasError}
102
+ >
103
+ <span className={cx('InputBox-caret')}>
104
+ <Icon icon="caret" className="icon" />
105
+ </span>
106
+ </InputBox>
107
+ )}
108
+ </PopOverContainer>
109
+ );
110
+ }
111
+ }
112
+
113
+ export default themeable(localeable(InputBoxWithSuggestion));
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import {autobind} from '../utils/helper';
2
+ import {autobind, isObject} from '../utils/helper';
3
3
  import Overlay from './Overlay';
4
4
  import PopOver from './PopOver';
5
5
  import {findDOMNode} from 'react-dom';
@@ -23,8 +23,9 @@ export interface PickerContainerProps extends ThemeProps, LocaleProps {
23
23
  onChange: (value: any) => void;
24
24
  setState: (state: any) => void;
25
25
  [propName: string]: any;
26
- }) => JSX.Element;
26
+ }) => JSX.Element | null;
27
27
  value?: any;
28
+ beforeConfirm?: (bodyRef: any) => any;
28
29
  onConfirm?: (value?: any) => void;
29
30
  onCancel?: () => void;
30
31
  popOverContainer?: any;
@@ -49,6 +50,7 @@ export class PickerContainer extends React.Component<
49
50
  isOpened: false,
50
51
  value: this.props.value
51
52
  };
53
+ bodyRef = React.createRef<any>();
52
54
 
53
55
  componentDidUpdate(prevProps: PickerContainerProps) {
54
56
  const props = this.props;
@@ -94,10 +96,22 @@ export class PickerContainer extends React.Component<
94
96
  }
95
97
 
96
98
  @autobind
97
- confirm() {
98
- const {onConfirm} = this.props;
99
+ async confirm() {
100
+ const {onConfirm, beforeConfirm} = this.props;
101
+
102
+ const ret = await beforeConfirm?.(this.bodyRef.current);
103
+ let state: any = {
104
+ isOpened: false
105
+ };
106
+
107
+ // beforeConfirm 返回 false 则阻止后续动作
108
+ if (ret === false) {
109
+ return;
110
+ } else if (isObject(ret)) {
111
+ state.value = ret;
112
+ }
99
113
 
100
- this.close(undefined, () => onConfirm?.(this.state.value));
114
+ this.setState(state, () => onConfirm?.(this.state.value));
101
115
  }
102
116
 
103
117
  @autobind
@@ -141,6 +155,7 @@ export class PickerContainer extends React.Component<
141
155
  <Modal.Body>
142
156
  {popOverRender({
143
157
  ...(this.state as any),
158
+ ref: this.bodyRef,
144
159
  setState: this.updateState,
145
160
  onClose: this.close,
146
161
  onChange: this.handleChange
@@ -60,6 +60,8 @@ export interface OptionProps {
60
60
  disabled?: boolean;
61
61
  creatable?: boolean;
62
62
  pathSeparator?: string;
63
+ hasError?: boolean;
64
+ block?: boolean;
63
65
  onAdd?: (
64
66
  idx?: number | Array<number>,
65
67
  value?: any,
@@ -476,7 +478,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
476
478
  const {simpleValue} = this.props;
477
479
  const {selection} = this.state;
478
480
  const value = simpleValue ? selection.map(item => item.value) : selection;
479
-
481
+
480
482
  this.props.disabled ||
481
483
  this.state.isOpen ||
482
484
  this.setState(
@@ -486,10 +488,11 @@ export class Select extends React.Component<SelectProps, SelectState> {
486
488
  this.focus
487
489
  );
488
490
 
489
- this.props.onFocus && this.props.onFocus({
490
- ...e,
491
- value
492
- });
491
+ this.props.onFocus &&
492
+ this.props.onFocus({
493
+ ...e,
494
+ value
495
+ });
493
496
  }
494
497
 
495
498
  @autobind
@@ -502,10 +505,11 @@ export class Select extends React.Component<SelectProps, SelectState> {
502
505
  isFocused: false
503
506
  });
504
507
 
505
- this.props.onBlur && this.props.onBlur({
506
- ...e,
507
- value
508
- });
508
+ this.props.onBlur &&
509
+ this.props.onBlur({
510
+ ...e,
511
+ value
512
+ });
509
513
  }
510
514
 
511
515
  @autobind
@@ -1093,6 +1097,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
1093
1097
  valuesNoWrap,
1094
1098
  searchable,
1095
1099
  inline,
1100
+ block,
1096
1101
  className,
1097
1102
  value,
1098
1103
  loading,
@@ -1101,7 +1106,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
1101
1106
  disabled,
1102
1107
  checkAll,
1103
1108
  borderMode,
1104
- useMobileUI
1109
+ useMobileUI,
1110
+ hasError
1105
1111
  } = this.props;
1106
1112
 
1107
1113
  const selection = this.state.selection;
@@ -1137,11 +1143,13 @@ export class Select extends React.Component<SelectProps, SelectState> {
1137
1143
  {
1138
1144
  [`Select--multi`]: multiple,
1139
1145
  [`Select--inline`]: inline,
1146
+ [`Select--block`]: block,
1140
1147
  [`Select--searchable`]: searchable,
1141
1148
  'is-opened': isOpen,
1142
1149
  'is-focused': this.state.isFocused,
1143
1150
  'is-disabled': disabled,
1144
1151
  'is-mobile': mobileUI,
1152
+ 'is-error': hasError,
1145
1153
  [`Select--border${ucFirst(borderMode)}`]: borderMode
1146
1154
  },
1147
1155
  className