amis 1.9.0 → 1.9.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) 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/actions/Action.d.ts +1 -0
  6. package/lib/actions/Action.js +7 -6
  7. package/lib/actions/Action.js.map +2 -2
  8. package/lib/components/Button.d.ts +11 -10
  9. package/lib/components/Button.js +2 -2
  10. package/lib/components/Button.js.map +2 -2
  11. package/lib/components/CalendarMobile.d.ts +40 -40
  12. package/lib/components/Checkbox.js +1 -1
  13. package/lib/components/Checkbox.js.map +2 -2
  14. package/lib/components/ContextMenu.d.ts +4 -0
  15. package/lib/components/ContextMenu.js +23 -7
  16. package/lib/components/ContextMenu.js.map +2 -2
  17. package/lib/components/DatePicker.d.ts +40 -40
  18. package/lib/components/DateRangePicker.d.ts +40 -40
  19. package/lib/components/Form.d.ts +22 -0
  20. package/lib/components/Form.js +44 -0
  21. package/lib/components/Form.js.map +13 -0
  22. package/lib/components/FormField.d.ts +65 -0
  23. package/lib/components/FormField.js +48 -0
  24. package/lib/components/FormField.js.map +13 -0
  25. package/lib/components/InputBox.d.ts +10 -10
  26. package/lib/components/InputBox.js +4 -3
  27. package/lib/components/InputBox.js.map +2 -2
  28. package/lib/components/InputBoxWithSuggestion.d.ts +280 -0
  29. package/lib/components/InputBoxWithSuggestion.js +65 -0
  30. package/lib/components/InputBoxWithSuggestion.js.map +13 -0
  31. package/lib/components/ListGroup.d.ts +10 -10
  32. package/lib/components/PickerContainer.d.ts +4 -2
  33. package/lib/components/PickerContainer.js +28 -5
  34. package/lib/components/PickerContainer.js.map +2 -2
  35. package/lib/components/Radios.d.ts +10 -10
  36. package/lib/components/ResultBox.d.ts +40 -40
  37. package/lib/components/Select.d.ts +195 -202
  38. package/lib/components/Select.js +7 -3
  39. package/lib/components/Select.js.map +2 -2
  40. package/lib/components/Textarea.d.ts +568 -2
  41. package/lib/components/Textarea.js +129 -1
  42. package/lib/components/Textarea.js.map +2 -2
  43. package/lib/components/Toast.js +11 -9
  44. package/lib/components/Toast.js.map +2 -2
  45. package/lib/components/UserSelect.d.ts +500 -0
  46. package/lib/components/UserSelect.js +559 -0
  47. package/lib/components/UserSelect.js.map +13 -0
  48. package/lib/components/UserTabSelect.d.ts +320 -0
  49. package/lib/components/UserTabSelect.js +163 -0
  50. package/lib/components/UserTabSelect.js.map +13 -0
  51. package/lib/components/WithRemoteConfig.d.ts +7 -0
  52. package/lib/components/WithRemoteConfig.js +17 -11
  53. package/lib/components/WithRemoteConfig.js.map +2 -2
  54. package/lib/components/calendar/DaysView.d.ts +26 -1
  55. package/lib/components/calendar/DaysView.js +60 -19
  56. package/lib/components/calendar/DaysView.js.map +2 -2
  57. package/lib/components/calendar/TimeView.d.ts +1 -1
  58. package/lib/components/calendar/TimeView.js +10 -3
  59. package/lib/components/calendar/TimeView.js.map +2 -2
  60. package/lib/components/formula/Picker.js +4 -4
  61. package/lib/components/formula/Picker.js.map +2 -2
  62. package/lib/components/icons.d.ts +7 -1
  63. package/lib/components/icons.js +17 -1
  64. package/lib/components/icons.js.map +2 -2
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/index.js +3 -1
  67. package/lib/components/index.js.map +2 -2
  68. package/lib/components/json-schema/Array.d.ts +3 -0
  69. package/lib/components/json-schema/Array.js +125 -0
  70. package/lib/components/json-schema/Array.js.map +13 -0
  71. package/lib/components/json-schema/Item.d.ts +3 -0
  72. package/lib/components/json-schema/Item.js +34 -0
  73. package/lib/components/json-schema/Item.js.map +13 -0
  74. package/lib/components/json-schema/Object.d.ts +3 -0
  75. package/lib/components/json-schema/Object.js +178 -0
  76. package/lib/components/json-schema/Object.js.map +13 -0
  77. package/lib/components/json-schema/index.d.ts +279 -0
  78. package/lib/components/json-schema/index.js +16 -0
  79. package/lib/components/json-schema/index.js.map +13 -0
  80. package/lib/components/schema-editor/Array.js +2 -2
  81. package/lib/components/schema-editor/Array.js.map +2 -2
  82. package/lib/components/schema-editor/Common.d.ts +2 -0
  83. package/lib/components/schema-editor/Common.js +39 -3
  84. package/lib/components/schema-editor/Common.js.map +2 -2
  85. package/lib/components/schema-editor/Object.js +2 -2
  86. package/lib/components/schema-editor/Object.js.map +2 -2
  87. package/lib/components/schema-editor/index.d.ts +45 -41
  88. package/lib/components/schema-editor/index.js +5 -5
  89. package/lib/components/schema-editor/index.js.map +2 -2
  90. package/lib/helper.css +125 -124
  91. package/lib/helper.css.map +1 -1
  92. package/lib/hooks/use-validation-resolver.d.ts +1 -0
  93. package/lib/hooks/use-validation-resolver.js +49 -0
  94. package/lib/hooks/use-validation-resolver.js.map +13 -0
  95. package/lib/icons/department.js +17 -0
  96. package/lib/icons/menu.js +9 -0
  97. package/lib/icons/post.js +15 -0
  98. package/lib/icons/role.js +14 -0
  99. package/lib/icons/user-remove.js +12 -0
  100. package/lib/index.d.ts +2 -0
  101. package/lib/index.js +3 -1
  102. package/lib/index.js.map +2 -2
  103. package/lib/locale/de-DE.js +11 -1
  104. package/lib/locale/de-DE.js.map +2 -2
  105. package/lib/locale/en-US.js +12 -1
  106. package/lib/locale/en-US.js.map +2 -2
  107. package/lib/locale/zh-CN.js +14 -3
  108. package/lib/locale/zh-CN.js.map +2 -2
  109. package/lib/renderers/Action.js +25 -11
  110. package/lib/renderers/Action.js.map +2 -2
  111. package/lib/renderers/CRUD.js +5 -1
  112. package/lib/renderers/CRUD.js.map +2 -2
  113. package/lib/renderers/Dialog.js +9 -3
  114. package/lib/renderers/Dialog.js.map +2 -2
  115. package/lib/renderers/Drawer.js +5 -1
  116. package/lib/renderers/Drawer.js.map +2 -2
  117. package/lib/renderers/Form/InputDate.d.ts +2 -2
  118. package/lib/renderers/Form/InputDate.js.map +2 -2
  119. package/lib/renderers/Form/InputFile.js +5 -12
  120. package/lib/renderers/Form/InputFile.js.map +2 -2
  121. package/lib/renderers/Form/InputText.d.ts +1 -1
  122. package/lib/renderers/Form/InputText.js.map +1 -1
  123. package/lib/renderers/Form/JSONSchema.d.ts +23 -0
  124. package/lib/renderers/Form/JSONSchema.js +44 -0
  125. package/lib/renderers/Form/JSONSchema.js.map +13 -0
  126. package/lib/renderers/Form/JSONSchemaEditor.d.ts +2 -3
  127. package/lib/renderers/Form/JSONSchemaEditor.js +9 -24
  128. package/lib/renderers/Form/JSONSchemaEditor.js.map +2 -2
  129. package/lib/renderers/Form/Textarea.d.ts +1 -8
  130. package/lib/renderers/Form/Textarea.js +11 -75
  131. package/lib/renderers/Form/Textarea.js.map +2 -2
  132. package/lib/renderers/Form/UserSelect.d.ts +54 -0
  133. package/lib/renderers/Form/UserSelect.js +197 -0
  134. package/lib/renderers/Form/UserSelect.js.map +13 -0
  135. package/lib/renderers/Form/index.d.ts +1 -1
  136. package/lib/renderers/Form/index.js +88 -42
  137. package/lib/renderers/Form/index.js.map +2 -2
  138. package/lib/renderers/Link.d.ts +1 -1
  139. package/lib/renderers/Link.js +15 -29
  140. package/lib/renderers/Link.js.map +2 -2
  141. package/lib/renderers/Log.d.ts +28 -0
  142. package/lib/renderers/Log.js +110 -20
  143. package/lib/renderers/Log.js.map +2 -2
  144. package/lib/renderers/Page.js +5 -1
  145. package/lib/renderers/Page.js.map +2 -2
  146. package/lib/renderers/Service.js +5 -1
  147. package/lib/renderers/Service.js.map +2 -2
  148. package/lib/renderers/Wizard.js +37 -14
  149. package/lib/renderers/Wizard.js.map +2 -2
  150. package/lib/store/form.js +65 -45
  151. package/lib/store/form.js.map +2 -2
  152. package/lib/themes/ang-ie11.css +576 -24
  153. package/lib/themes/ang.css +553 -12
  154. package/lib/themes/ang.css.map +1 -1
  155. package/lib/themes/antd-ie11.css +576 -24
  156. package/lib/themes/antd.css +553 -12
  157. package/lib/themes/antd.css.map +1 -1
  158. package/lib/themes/cxd-ie11.css +576 -24
  159. package/lib/themes/cxd.css +553 -12
  160. package/lib/themes/cxd.css.map +1 -1
  161. package/lib/themes/dark-ie11.css +576 -24
  162. package/lib/themes/dark.css +553 -12
  163. package/lib/themes/dark.css.map +1 -1
  164. package/lib/themes/default-ie11.css +576 -24
  165. package/lib/themes/default.css +553 -12
  166. package/lib/themes/default.css.map +1 -1
  167. package/lib/utils/api.js +1 -1
  168. package/lib/utils/api.js.map +2 -2
  169. package/lib/utils/renderer-event.js.map +2 -2
  170. package/package.json +2 -1
  171. package/schema.json +542 -4
  172. package/scss/_properties.scss +20 -8
  173. package/scss/components/_input-box.scss +22 -1
  174. package/scss/components/_json-schema.scss +124 -0
  175. package/scss/components/_log.scss +37 -5
  176. package/scss/components/form/_date-range.scss +1 -0
  177. package/scss/components/form/_select.scss +9 -0
  178. package/scss/components/form/_transfer.scss +19 -3
  179. package/scss/components/form/_user-select.scss +422 -0
  180. package/scss/helper/background/_background-color.scss +125 -124
  181. package/scss/themes/_common.scss +2 -0
  182. package/sdk/ang-ie11.css +670 -24
  183. package/sdk/ang.css +647 -12
  184. package/sdk/antd-ie11.css +670 -24
  185. package/sdk/antd.css +647 -12
  186. package/sdk/barcode.js +51 -51
  187. package/sdk/charts.js +14 -14
  188. package/sdk/codemirror.js +7 -7
  189. package/sdk/color-picker.js +65 -65
  190. package/sdk/cropperjs.js +2 -2
  191. package/sdk/cxd-ie11.css +670 -24
  192. package/sdk/cxd.css +647 -12
  193. package/sdk/dark-ie11.css +670 -24
  194. package/sdk/dark.css +647 -12
  195. package/sdk/exceljs.js +1 -1
  196. package/sdk/helper.css +125 -124
  197. package/sdk/helper.css.map +1 -1
  198. package/sdk/locale/de-DE.js +11 -1
  199. package/sdk/markdown.js +69 -69
  200. package/sdk/papaparse.js +1 -1
  201. package/sdk/renderers/Form/CityDB.js +1 -1
  202. package/sdk/rest.js +16 -16
  203. package/sdk/rich-text.js +62 -62
  204. package/sdk/sdk-ie11.css +670 -24
  205. package/sdk/sdk.css +647 -12
  206. package/sdk/sdk.js +1651 -1637
  207. package/sdk/thirds/hls.js/hls.js +1 -1
  208. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  209. package/sdk/tinymce.js +57 -57
  210. package/src/RootRenderer.tsx +27 -15
  211. package/src/Schema.ts +5 -1
  212. package/src/actions/Action.ts +5 -4
  213. package/src/components/Button.tsx +3 -0
  214. package/src/components/Checkbox.tsx +2 -1
  215. package/src/components/ContextMenu.tsx +25 -7
  216. package/src/components/Form.tsx +70 -0
  217. package/src/components/FormField.tsx +127 -0
  218. package/src/components/InputBox.tsx +4 -1
  219. package/src/components/InputBoxWithSuggestion.tsx +113 -0
  220. package/src/components/PickerContainer.tsx +20 -5
  221. package/src/components/Select.tsx +18 -10
  222. package/src/components/Textarea.tsx +234 -2
  223. package/src/components/Toast.tsx +19 -18
  224. package/src/components/UserSelect.tsx +850 -0
  225. package/src/components/UserTabSelect.tsx +261 -0
  226. package/src/components/WithRemoteConfig.tsx +22 -7
  227. package/src/components/calendar/DaysView.tsx +117 -49
  228. package/src/components/calendar/TimeView.tsx +11 -6
  229. package/src/components/formula/Picker.tsx +2 -1
  230. package/src/components/icons.tsx +17 -1
  231. package/src/components/index.tsx +3 -1
  232. package/src/components/json-schema/Array.tsx +216 -0
  233. package/src/components/json-schema/Item.tsx +47 -0
  234. package/src/components/json-schema/Object.tsx +339 -0
  235. package/src/components/json-schema/index.tsx +44 -0
  236. package/src/components/schema-editor/Array.tsx +3 -1
  237. package/src/components/schema-editor/Common.tsx +61 -4
  238. package/src/components/schema-editor/Object.tsx +3 -1
  239. package/src/components/schema-editor/index.tsx +12 -5
  240. package/src/hooks/use-validation-resolver.ts +45 -0
  241. package/src/icons/department.svg +17 -0
  242. package/src/icons/menu.svg +2 -0
  243. package/src/icons/post.svg +15 -0
  244. package/src/icons/role.svg +14 -0
  245. package/src/icons/user-remove.svg +12 -0
  246. package/src/index.tsx +2 -0
  247. package/src/locale/de-DE.ts +11 -1
  248. package/src/locale/en-US.ts +12 -1
  249. package/src/locale/zh-CN.ts +14 -3
  250. package/src/renderers/Action.tsx +10 -9
  251. package/src/renderers/CRUD.tsx +5 -1
  252. package/src/renderers/Dialog.tsx +9 -3
  253. package/src/renderers/Drawer.tsx +5 -1
  254. package/src/renderers/Form/InputDate.tsx +9 -4
  255. package/src/renderers/Form/InputFile.tsx +5 -15
  256. package/src/renderers/Form/InputText.tsx +1 -1
  257. package/src/renderers/Form/JSONSchema.tsx +56 -0
  258. package/src/renderers/Form/JSONSchemaEditor.tsx +8 -27
  259. package/src/renderers/Form/Textarea.tsx +7 -117
  260. package/src/renderers/Form/UserSelect.tsx +263 -0
  261. package/src/renderers/Form/index.tsx +28 -18
  262. package/src/renderers/Link.tsx +5 -17
  263. package/src/renderers/Log.tsx +213 -19
  264. package/src/renderers/Page.tsx +6 -1
  265. package/src/renderers/Service.tsx +5 -1
  266. package/src/renderers/Wizard.tsx +24 -10
  267. package/src/store/form.ts +24 -17
  268. package/src/utils/api.ts +1 -1
  269. 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
@@ -26,6 +26,7 @@ export interface ListenerAction {
26
26
  preventDefault?: boolean; // 阻止原有组件的动作行为
27
27
  stopPropagation?: boolean; // 阻止后续的事件处理器执行
28
28
  expression?: string; // 执行条件
29
+ execOn?: string; // 执行条件,1.9.0废弃
29
30
  }
30
31
 
31
32
  export interface ILogicAction extends ListenerAction {
@@ -119,10 +120,10 @@ export const runAction = async (
119
120
  event
120
121
  });
121
122
 
122
- if (
123
- actionConfig.expression &&
124
- !evalExpression(actionConfig.expression, mergeData)
125
- ) {
123
+ // 兼容一下1.9.0之前的版本
124
+ const expression = actionConfig.expression ?? actionConfig.execOn;
125
+
126
+ if (expression && !evalExpression(expression, mergeData)) {
126
127
  return;
127
128
  }
128
129
 
@@ -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