amis 1.8.0-beta.1 → 1.8.0-beta.5

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 (207) hide show
  1. package/lib/SchemaRenderer.js +19 -3
  2. package/lib/SchemaRenderer.js.map +2 -2
  3. package/lib/WithRootStore.d.ts +18 -0
  4. package/lib/WithStore.js +2 -1
  5. package/lib/WithStore.js.map +2 -2
  6. package/lib/actions/CmptAction.js +14 -3
  7. package/lib/actions/CmptAction.js.map +2 -2
  8. package/lib/components/AssociatedSelection.js +9 -2
  9. package/lib/components/AssociatedSelection.js.map +2 -2
  10. package/lib/components/BarCode.js +1 -1
  11. package/lib/components/BarCode.js.map +2 -2
  12. package/lib/components/Checkbox.d.ts +24 -23
  13. package/lib/components/Checkbox.js +6 -2
  14. package/lib/components/Checkbox.js.map +2 -2
  15. package/lib/components/DatePicker.js +16 -5
  16. package/lib/components/DatePicker.js.map +2 -2
  17. package/lib/components/DateRangePicker.d.ts +94 -84
  18. package/lib/components/DateRangePicker.js +259 -7
  19. package/lib/components/DateRangePicker.js.map +2 -2
  20. package/lib/components/MonthRangePicker.d.ts +84 -84
  21. package/lib/components/Radios.d.ts +22 -22
  22. package/lib/components/Radios.js +3 -5
  23. package/lib/components/Radios.js.map +2 -2
  24. package/lib/components/Range.d.ts +2 -2
  25. package/lib/components/Range.js +24 -11
  26. package/lib/components/Range.js.map +2 -2
  27. package/lib/components/Steps.d.ts +6 -0
  28. package/lib/components/Steps.js +13 -9
  29. package/lib/components/Steps.js.map +2 -2
  30. package/lib/components/calendar/Calendar.js +2 -14
  31. package/lib/components/calendar/Calendar.js.map +2 -2
  32. package/lib/components/calendar/YearsView.js +3 -3
  33. package/lib/components/calendar/YearsView.js.map +2 -2
  34. package/lib/factory.d.ts +4 -0
  35. package/lib/factory.js +9 -0
  36. package/lib/factory.js.map +2 -2
  37. package/lib/index.js +1 -1
  38. package/lib/locale/de-DE.js +13 -0
  39. package/lib/locale/de-DE.js.map +2 -2
  40. package/lib/locale/en-US.js +13 -0
  41. package/lib/locale/en-US.js.map +2 -2
  42. package/lib/locale/zh-CN.js +13 -0
  43. package/lib/locale/zh-CN.js.map +2 -2
  44. package/lib/renderers/Action.d.ts +2 -0
  45. package/lib/renderers/Action.js +23 -5
  46. package/lib/renderers/Action.js.map +2 -2
  47. package/lib/renderers/CRUD.d.ts +8 -0
  48. package/lib/renderers/CRUD.js +11 -4
  49. package/lib/renderers/CRUD.js.map +2 -2
  50. package/lib/renderers/Carousel.d.ts +1 -0
  51. package/lib/renderers/Carousel.js +13 -1
  52. package/lib/renderers/Carousel.js.map +2 -2
  53. package/lib/renderers/Form/Checkbox.d.ts +5 -2
  54. package/lib/renderers/Form/Checkbox.js +2 -2
  55. package/lib/renderers/Form/Checkbox.js.map +2 -2
  56. package/lib/renderers/Form/Checkboxes.d.ts +7 -2
  57. package/lib/renderers/Form/Checkboxes.js +101 -12
  58. package/lib/renderers/Form/Checkboxes.js.map +2 -2
  59. package/lib/renderers/Form/Combo.js +3 -2
  60. package/lib/renderers/Form/Combo.js.map +2 -2
  61. package/lib/renderers/Form/InputCity.d.ts +3 -0
  62. package/lib/renderers/Form/InputCity.js +44 -2
  63. package/lib/renderers/Form/InputCity.js.map +2 -2
  64. package/lib/renderers/Form/InputDateRange.d.ts +5 -0
  65. package/lib/renderers/Form/InputDateRange.js.map +2 -2
  66. package/lib/renderers/Form/InputFile.js +6 -3
  67. package/lib/renderers/Form/InputFile.js.map +2 -2
  68. package/lib/renderers/Form/InputImage.js +6 -3
  69. package/lib/renderers/Form/InputImage.js.map +2 -2
  70. package/lib/renderers/Form/InputRange.js +13 -14
  71. package/lib/renderers/Form/InputRange.js.map +2 -2
  72. package/lib/renderers/Form/Item.d.ts +11 -6
  73. package/lib/renderers/Form/Item.js +3 -1
  74. package/lib/renderers/Form/Item.js.map +2 -2
  75. package/lib/renderers/Form/index.d.ts +1 -0
  76. package/lib/renderers/Form/index.js +1 -1
  77. package/lib/renderers/Form/index.js.map +2 -2
  78. package/lib/renderers/Form/wrapControl.d.ts +9 -0
  79. package/lib/renderers/Form/wrapControl.js +1 -1
  80. package/lib/renderers/Form/wrapControl.js.map +2 -2
  81. package/lib/renderers/Nav.js +2 -2
  82. package/lib/renderers/Nav.js.map +2 -2
  83. package/lib/renderers/Steps.d.ts +8 -0
  84. package/lib/renderers/Steps.js +2 -2
  85. package/lib/renderers/Steps.js.map +2 -2
  86. package/lib/renderers/Table/index.d.ts +1 -0
  87. package/lib/renderers/Table/index.js +10 -5
  88. package/lib/renderers/Table/index.js.map +2 -2
  89. package/lib/renderers/Tabs.d.ts +4 -0
  90. package/lib/renderers/Tabs.js +22 -6
  91. package/lib/renderers/Tabs.js.map +2 -2
  92. package/lib/renderers/Wizard.d.ts +6 -3
  93. package/lib/renderers/Wizard.js +257 -152
  94. package/lib/renderers/Wizard.js.map +2 -2
  95. package/lib/store/crud.d.ts +1 -0
  96. package/lib/store/crud.js +33 -7
  97. package/lib/store/crud.js.map +2 -2
  98. package/lib/store/formItem.js +1 -1
  99. package/lib/store/formItem.js.map +2 -2
  100. package/lib/store/index.d.ts +5 -0
  101. package/lib/store/index.js +14 -0
  102. package/lib/store/index.js.map +2 -2
  103. package/lib/store/table.js +2 -2
  104. package/lib/store/table.js.map +2 -2
  105. package/lib/themes/ang-ie11.css +278 -17
  106. package/lib/themes/ang.css +286 -17
  107. package/lib/themes/ang.css.map +1 -1
  108. package/lib/themes/antd-ie11.css +278 -17
  109. package/lib/themes/antd.css +286 -17
  110. package/lib/themes/antd.css.map +1 -1
  111. package/lib/themes/cxd-ie11.css +278 -17
  112. package/lib/themes/cxd.css +286 -17
  113. package/lib/themes/cxd.css.map +1 -1
  114. package/lib/themes/dark-ie11.css +278 -17
  115. package/lib/themes/dark.css +286 -17
  116. package/lib/themes/dark.css.map +1 -1
  117. package/lib/themes/default-ie11.css +278 -17
  118. package/lib/themes/default.css +286 -17
  119. package/lib/themes/default.css.map +1 -1
  120. package/lib/types.d.ts +1 -1
  121. package/lib/types.js.map +1 -1
  122. package/lib/utils/columnsSplit.d.ts +1 -0
  123. package/lib/utils/columnsSplit.js +40 -0
  124. package/lib/utils/columnsSplit.js.map +13 -0
  125. package/lib/utils/debug.d.ts +1 -1
  126. package/lib/utils/debug.js +16 -22
  127. package/lib/utils/debug.js.map +2 -2
  128. package/package.json +1 -1
  129. package/schema.json +237 -29
  130. package/scss/_properties.scss +10 -1
  131. package/scss/components/_barcode.scss +1 -1
  132. package/scss/components/_carousel.scss +1 -0
  133. package/scss/components/_debug.scss +3 -3
  134. package/scss/components/_steps.scss +199 -8
  135. package/scss/components/form/_checks.scss +122 -1
  136. package/scss/components/form/_date.scss +2 -1
  137. package/scss/components/form/_editor.scss +2 -1
  138. package/scss/components/form/_form.scss +16 -0
  139. package/sdk/ang-ie11.css +335 -18
  140. package/sdk/ang.css +343 -18
  141. package/sdk/antd-ie11.css +335 -18
  142. package/sdk/antd.css +343 -18
  143. package/sdk/barcode.js +51 -51
  144. package/sdk/charts.js +14 -14
  145. package/sdk/codemirror.js +7 -7
  146. package/sdk/color-picker.js +65 -65
  147. package/sdk/cropperjs.js +2 -2
  148. package/sdk/cxd-ie11.css +335 -18
  149. package/sdk/cxd.css +343 -18
  150. package/sdk/dark-ie11.css +335 -18
  151. package/sdk/dark.css +343 -18
  152. package/sdk/exceljs.js +1 -1
  153. package/sdk/locale/de-DE.js +13 -0
  154. package/sdk/markdown.js +69 -69
  155. package/sdk/papaparse.js +1 -1
  156. package/sdk/renderers/Form/CityDB.js +1 -1
  157. package/sdk/rest.js +17 -17
  158. package/sdk/rich-text.js +62 -62
  159. package/sdk/sdk-ie11.css +335 -18
  160. package/sdk/sdk.css +343 -18
  161. package/sdk/sdk.js +1289 -1287
  162. package/sdk/thirds/hls.js/hls.js +1 -1
  163. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  164. package/sdk/tinymce.js +57 -57
  165. package/src/SchemaRenderer.tsx +32 -14
  166. package/src/WithStore.tsx +3 -1
  167. package/src/actions/CmptAction.ts +18 -0
  168. package/src/components/AssociatedSelection.tsx +9 -3
  169. package/src/components/BarCode.tsx +2 -2
  170. package/src/components/Checkbox.tsx +11 -5
  171. package/src/components/DatePicker.tsx +21 -4
  172. package/src/components/DateRangePicker.tsx +295 -6
  173. package/src/components/Radios.tsx +6 -17
  174. package/src/components/Range.tsx +26 -12
  175. package/src/components/Steps.tsx +28 -27
  176. package/src/components/calendar/Calendar.tsx +2 -15
  177. package/src/components/calendar/YearsView.tsx +3 -4
  178. package/src/factory.tsx +16 -0
  179. package/src/locale/de-DE.ts +13 -0
  180. package/src/locale/en-US.ts +13 -0
  181. package/src/locale/zh-CN.ts +13 -0
  182. package/src/renderers/Action.tsx +22 -1
  183. package/src/renderers/CRUD.tsx +22 -4
  184. package/src/renderers/Carousel.tsx +8 -0
  185. package/src/renderers/Form/Checkbox.tsx +11 -2
  186. package/src/renderers/Form/Checkboxes.tsx +106 -23
  187. package/src/renderers/Form/Combo.tsx +2 -3
  188. package/src/renderers/Form/InputCity.tsx +33 -4
  189. package/src/renderers/Form/InputDateRange.tsx +8 -1
  190. package/src/renderers/Form/InputFile.tsx +7 -3
  191. package/src/renderers/Form/InputImage.tsx +7 -3
  192. package/src/renderers/Form/InputRange.tsx +18 -16
  193. package/src/renderers/Form/Item.tsx +1 -0
  194. package/src/renderers/Form/index.tsx +2 -1
  195. package/src/renderers/Form/wrapControl.tsx +1 -1
  196. package/src/renderers/Nav.tsx +1 -1
  197. package/src/renderers/Steps.tsx +14 -0
  198. package/src/renderers/Table/index.tsx +15 -4
  199. package/src/renderers/Tabs.tsx +75 -28
  200. package/src/renderers/Wizard.tsx +154 -93
  201. package/src/store/crud.ts +40 -5
  202. package/src/store/formItem.ts +1 -2
  203. package/src/store/index.ts +20 -0
  204. package/src/store/table.ts +2 -2
  205. package/src/types.ts +3 -1
  206. package/src/utils/columnsSplit.tsx +57 -0
  207. package/src/utils/debug.tsx +17 -24
@@ -15,12 +15,14 @@ import {asFormItem} from './renderers/Form/Item';
15
15
  import {renderChild, renderChildren} from './Root';
16
16
  import {IScopedContext, ScopedContext} from './Scoped';
17
17
  import {Schema, SchemaNode} from './types';
18
- import {DebugWrapper, enableAMISDebug} from './utils/debug';
18
+ import {DebugWrapper} from './utils/debug';
19
19
  import getExprProperties from './utils/filter-schema';
20
20
  import {anyChanged, chainEvents, autobind} from './utils/helper';
21
21
  import {SimpleMap} from './utils/SimpleMap';
22
22
 
23
23
  import type {RendererEvent} from './utils/renderer-event';
24
+ import {observer} from 'mobx-react';
25
+ import {isAlive} from 'mobx-state-tree';
24
26
 
25
27
  interface SchemaRendererProps extends Partial<RendererProps> {
26
28
  schema: Schema;
@@ -59,6 +61,7 @@ const defaultOmitList = [
59
61
 
60
62
  const componentCache: SimpleMap = new SimpleMap();
61
63
 
64
+ @observer
62
65
  class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
63
66
  ref: any;
64
67
  unbindEvent: (() => void) | undefined = undefined;
@@ -99,21 +102,36 @@ class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
99
102
  }
100
103
 
101
104
  render() {
102
- const {component: Component, ...rest} = this.props;
103
-
105
+ const {component: Component, rootStore, ...rest} = this.props;
106
+ const visible = isAlive(rootStore)
107
+ ? rootStore.visibleState[rest.$schema.id || rest.$path]
108
+ : true;
109
+ const disable = isAlive(rootStore)
110
+ ? rootStore.disableState[rest.$schema.id || rest.$path]
111
+ : false;
104
112
  const isClassComponent = Component.prototype?.isReactComponent;
105
113
 
106
- // 函数组件不支持 ref https://reactjs.org/docs/refs-and-the-dom.html#refs-and-function-components
114
+ if (disable) {
115
+ (rest as any).disabled = true;
116
+ }
107
117
 
108
- return isClassComponent ? (
109
- <Component
110
- ref={this.childRef}
111
- {...rest}
112
- dispatchEvent={this.dispatchEvent}
113
- />
114
- ) : (
115
- <Component {...rest} dispatchEvent={this.dispatchEvent} />
116
- );
118
+ // 函数组件不支持 ref https://reactjs.org/docs/refs-and-the-dom.html#refs-and-function-components
119
+ return visible !== false ? (
120
+ isClassComponent ? (
121
+ <Component
122
+ ref={this.childRef}
123
+ {...rest}
124
+ rootStore={rootStore}
125
+ dispatchEvent={this.dispatchEvent}
126
+ />
127
+ ) : (
128
+ <Component
129
+ {...rest}
130
+ rootStore={rootStore}
131
+ dispatchEvent={this.dispatchEvent}
132
+ />
133
+ )
134
+ ) : null;
117
135
  }
118
136
  }
119
137
 
@@ -399,7 +417,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
399
417
  />
400
418
  );
401
419
 
402
- return enableAMISDebug ? (
420
+ return this.props.env.enableAMISDebug ? (
403
421
  <DebugWrapper renderer={renderer}>{component}</DebugWrapper>
404
422
  ) : (
405
423
  component
package/src/WithStore.tsx CHANGED
@@ -1,5 +1,6 @@
1
1
  import hoistNonReactStatic from 'hoist-non-react-statics';
2
2
  import {observer} from 'mobx-react';
3
+ import {isAlive} from 'mobx-state-tree';
3
4
  import React from 'react';
4
5
  import {RendererProps} from './factory';
5
6
  import {IIRendererStore, IRendererStore} from './store';
@@ -257,7 +258,8 @@ export function HocStoreFactory(renderer: {
257
258
  componentWillUnmount() {
258
259
  const rootStore = this.context as IRendererStore;
259
260
  const store = this.store;
260
- rootStore.removeStore(store);
261
+
262
+ isAlive(store) && rootStore.removeStore(store);
261
263
 
262
264
  // @ts-ignore
263
265
  delete this.store;
@@ -21,6 +21,19 @@ export class CmptAction implements Action {
21
21
  renderer: ListenerContext,
22
22
  event: RendererEvent<any>
23
23
  ) {
24
+ // 显隐&状态控制
25
+ if (['show', 'hidden'].includes(action.actionType)) {
26
+ return renderer.props.rootStore.setVisible(
27
+ action.componentId,
28
+ action.actionType === 'show'
29
+ );
30
+ } else if (['enabled', 'disabled'].includes(action.actionType)) {
31
+ return renderer.props.rootStore.setDisable(
32
+ action.componentId,
33
+ action.actionType === 'disabled'
34
+ );
35
+ }
36
+
24
37
  /**
25
38
  * 根据唯一ID查找指定组件
26
39
  * 触发组件未指定id或未指定响应组件componentId,则使用触发组件响应
@@ -30,6 +43,11 @@ export class CmptAction implements Action {
30
43
  ? event.context.scoped?.getComponentById(action.componentId)
31
44
  : renderer;
32
45
 
46
+ // 刷新
47
+ if (action.actionType === 'reload') {
48
+ return component.reload?.(undefined, action.args);
49
+ }
50
+
33
51
  // 执行组件动作
34
52
  return component.doAction?.(action, action.args);
35
53
  }
@@ -88,9 +88,15 @@ export class AssociatedSelection extends BaseSelection<
88
88
 
89
89
  @autobind
90
90
  handleLeftDeferLoad(option: Option) {
91
- const {leftOptions, onLeftDeferLoad} = this.props;
92
-
93
- onLeftDeferLoad?.(option, leftOptions);
91
+ const {leftOptions, onLeftDeferLoad, onDeferLoad} = this.props;
92
+
93
+ if (typeof onLeftDeferLoad === 'function') {
94
+ // TabsTransfer
95
+ return onLeftDeferLoad?.(option, leftOptions);
96
+ } else if (typeof onDeferLoad === 'function') {
97
+ // Select
98
+ return onDeferLoad?.(option);
99
+ }
94
100
  }
95
101
 
96
102
  handleRetry(option: Option) {
@@ -20,7 +20,7 @@ export class BarCode extends React.Component<BarCodeProps> {
20
20
 
21
21
  constructor(props: BarCodeProps) {
22
22
  super(props);
23
- this.dom = React.createRef<SVGSVGElement>();
23
+ this.dom = React.createRef<HTMLImageElement>();
24
24
  }
25
25
 
26
26
  componentDidUpdate(prevProps: BarCodeProps) {
@@ -43,7 +43,7 @@ export class BarCode extends React.Component<BarCodeProps> {
43
43
  }
44
44
 
45
45
  render() {
46
- return <svg ref={this.dom}></svg>;
46
+ return <img ref={this.dom} />;
47
47
  }
48
48
  }
49
49
 
@@ -16,10 +16,10 @@ interface CheckboxProps {
16
16
  labelClassName?: string;
17
17
  className?: string;
18
18
  onChange?: (value: any, shift?: boolean) => void;
19
- value?: any;
19
+ value?: boolean | string | number;
20
20
  inline?: boolean;
21
- trueValue?: any;
22
- falseValue?: any;
21
+ trueValue?: boolean | string | number;
22
+ falseValue?: boolean | string | number;
23
23
  disabled?: boolean;
24
24
  readOnly?: boolean;
25
25
  checked?: boolean;
@@ -28,6 +28,7 @@ interface CheckboxProps {
28
28
  classPrefix: string;
29
29
  classnames: ClassNamesFn;
30
30
  partial?: boolean;
31
+ optionType?: 'default' | 'button';
31
32
  }
32
33
 
33
34
  export class Checkbox extends React.Component<CheckboxProps, any> {
@@ -70,14 +71,19 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
70
71
  checked,
71
72
  type,
72
73
  name,
73
- labelClassName
74
+ labelClassName,
75
+ optionType
74
76
  } = this.props;
75
77
 
76
78
  return (
77
79
  <label
78
80
  className={cx(`Checkbox Checkbox--${type}`, className, {
79
81
  'Checkbox--full': !partial,
80
- [`Checkbox--${size}`]: size
82
+ 'Checkbox--partial': partial,
83
+ [`Checkbox--${size}`]: size,
84
+ 'Checkbox--button': optionType === 'button',
85
+ 'Checkbox--button--checked': optionType === 'button' && checked,
86
+ 'Checkbox--button--disabled--unchecked': disabled && !checked
81
87
  })}
82
88
  >
83
89
  <input
@@ -364,10 +364,25 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
364
364
  componentDidUpdate(prevProps: DateProps) {
365
365
  const props = this.props;
366
366
 
367
- if (prevProps.value !== props.value) {
368
- this.setState({
367
+ const prevValue = prevProps.value;
368
+
369
+ if (prevValue !== props.value) {
370
+ const newState: any = {
369
371
  value: normalizeValue(props.value, props.format)
370
- });
372
+ };
373
+ // 相对值和公式是 didUpdate 的时候才更新
374
+ if (
375
+ typeof prevValue === 'string' &&
376
+ (prevValue.startsWith('+') ||
377
+ prevValue.startsWith('-') ||
378
+ prevValue.startsWith('$'))
379
+ ) {
380
+ newState.inputValue =
381
+ normalizeValue(this.props.value, this.props.format)?.format(
382
+ this.props.inputFormat
383
+ ) || '';
384
+ }
385
+ this.setState(newState);
371
386
  }
372
387
  }
373
388
 
@@ -724,7 +739,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
724
739
  `DatePicker`,
725
740
  {
726
741
  'is-disabled': disabled,
727
- 'is-focused': this.state.isFocused,
742
+ 'is-focused': !disabled && this.state.isFocused,
728
743
  [`DatePicker--border${ucFirst(borderMode)}`]: borderMode,
729
744
  'is-mobile': useMobileUI && isMobile()
730
745
  },
@@ -734,11 +749,13 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
734
749
  onClick={this.handleClick}
735
750
  >
736
751
  <Input
752
+ className={cx('DatePicker-input')}
737
753
  onChange={this.inputChange}
738
754
  ref={this.inputRef}
739
755
  placeholder={__(placeholder)}
740
756
  autoComplete="off"
741
757
  value={this.state.inputValue}
758
+ disabled={disabled}
742
759
  />
743
760
 
744
761
  {clearable && !disabled && normalizeValue(value, format) ? (
@@ -82,8 +82,19 @@ export const availableRanges: {[propName: string]: any} = {
82
82
  }
83
83
  },
84
84
 
85
- '1dayago': {
86
- label: 'DateRange.1dayago',
85
+ 'tomorrow': {
86
+ label: 'Date.tomorrow',
87
+ startDate: (now: moment.Moment) => {
88
+ return now.add(1, 'days').startOf('day');
89
+ },
90
+ endDate: (now: moment.Moment) => {
91
+ return now.add(1, 'days').endOf('day');
92
+ }
93
+ },
94
+
95
+ // 兼容一下错误的用法
96
+ '1daysago': {
97
+ label: 'DateRange.1daysago',
87
98
  startDate: (now: moment.Moment) => {
88
99
  return now.add(-1, 'days');
89
100
  },
@@ -203,6 +214,177 @@ export const availableRanges: {[propName: string]: any} = {
203
214
  }
204
215
  };
205
216
 
217
+ export const advancedRanges = [
218
+ {
219
+ regexp: /^(\d+)hoursago$/,
220
+ resolve: (__: any, _: string, hours: string) => {
221
+ return {
222
+ label: __('DateRange.hoursago', {hours}),
223
+ startDate: (now: moment.Moment) => {
224
+ return now.add(-hours, 'hours').startOf('hour');
225
+ },
226
+ endDate: (now: moment.Moment) => {
227
+ return now.add(-1, 'hours').endOf('hours');
228
+ }
229
+ };
230
+ }
231
+ },
232
+ {
233
+ regexp: /^(\d+)hourslater$/,
234
+ resolve: (__: any, _: string, hours: string) => {
235
+ return {
236
+ label: __('DateRange.hourslater', {hours}),
237
+ startDate: (now: moment.Moment) => {
238
+ return now.startOf('hour');
239
+ },
240
+ endDate: (now: moment.Moment) => {
241
+ return now.add(hours, 'hours').endOf('hour');
242
+ }
243
+ };
244
+ }
245
+ },
246
+ {
247
+ regexp: /^(\d+)daysago$/,
248
+ resolve: (__: any, _: string, days: string) => {
249
+ return {
250
+ label: __('DateRange.daysago', {days}),
251
+ startDate: (now: moment.Moment) => {
252
+ return now.add(-days, 'days').startOf('day');
253
+ },
254
+ endDate: (now: moment.Moment) => {
255
+ return now.add(-1, 'days').endOf('day');
256
+ }
257
+ };
258
+ }
259
+ },
260
+ {
261
+ regexp: /^(\d+)dayslater$/,
262
+ resolve: (__: any, _: string, days: string) => {
263
+ return {
264
+ label: __('DateRange.dayslater', {days}),
265
+ startDate: (now: moment.Moment) => {
266
+ return now.startOf('day');
267
+ },
268
+ endDate: (now: moment.Moment) => {
269
+ return now.add(days, 'days').endOf('day');
270
+ }
271
+ };
272
+ }
273
+ },
274
+ {
275
+ regexp: /^(\d+)weeksago$/,
276
+ resolve: (__: any, _: string, weeks: string) => {
277
+ return {
278
+ label: __('DateRange.weeksago', {weeks}),
279
+ startDate: (now: moment.Moment) => {
280
+ return now.startOf('week').add(-weeks, 'weeks');
281
+ },
282
+ endDate: (now: moment.Moment) => {
283
+ return now.startOf('week').add(-1, 'days').endOf('day');
284
+ }
285
+ };
286
+ }
287
+ },
288
+ {
289
+ regexp: /^(\d+)weekslater$/,
290
+ resolve: (__: any, _: string, weeks: string) => {
291
+ return {
292
+ label: __('DateRange.weekslater', {weeks}),
293
+ startDate: (now: moment.Moment) => {
294
+ return now.startOf('week');
295
+ },
296
+ endDate: (now: moment.Moment) => {
297
+ return now.startOf('week').add(weeks, 'weeks').endOf('day');
298
+ }
299
+ };
300
+ }
301
+ },
302
+ {
303
+ regexp: /^(\d+)monthsago$/,
304
+ resolve: (__: any, _: string, months: string) => {
305
+ return {
306
+ label: __('DateRange.monthsago', {months}),
307
+ startDate: (now: moment.Moment) => {
308
+ return now.startOf('months').add(-months, 'months');
309
+ },
310
+ endDate: (now: moment.Moment) => {
311
+ return now.startOf('month').add(-1, 'days').endOf('day');
312
+ }
313
+ };
314
+ }
315
+ },
316
+ {
317
+ regexp: /^(\d+)monthslater$/,
318
+ resolve: (__: any, _: string, months: string) => {
319
+ return {
320
+ label: __('DateRange.monthslater', {months}),
321
+ startDate: (now: moment.Moment) => {
322
+ return now.startOf('month');
323
+ },
324
+ endDate: (now: moment.Moment) => {
325
+ return now.startOf('month').add(months, 'months').endOf('day');
326
+ }
327
+ };
328
+ }
329
+ },
330
+ {
331
+ regexp: /^(\d+)quartersago$/,
332
+ resolve: (__: any, _: string, quarters: string) => {
333
+ return {
334
+ label: __('DateRange.quartersago', {quarters}),
335
+ startDate: (now: moment.Moment) => {
336
+ return now.startOf('quarters').add(-quarters, 'quarters');
337
+ },
338
+ endDate: (now: moment.Moment) => {
339
+ return now.startOf('quarter').add(-1, 'days').endOf('day');
340
+ }
341
+ };
342
+ }
343
+ },
344
+ {
345
+ regexp: /^(\d+)quarterslater$/,
346
+ resolve: (__: any, _: string, quarters: string) => {
347
+ return {
348
+ label: __('DateRange.quarterslater', {quarters}),
349
+ startDate: (now: moment.Moment) => {
350
+ return now.startOf('quarter');
351
+ },
352
+ endDate: (now: moment.Moment) => {
353
+ return now.startOf('quarter').add(quarters, 'quarters').endOf('day');
354
+ }
355
+ };
356
+ }
357
+ },
358
+ {
359
+ regexp: /^(\d+)yearsago$/,
360
+ resolve: (__: any, _: string, years: string) => {
361
+ return {
362
+ label: __('DateRange.yearsago', {years}),
363
+ startDate: (now: moment.Moment) => {
364
+ return now.startOf('years').add(-years, 'years');
365
+ },
366
+ endDate: (now: moment.Moment) => {
367
+ return now.startOf('year').add(-1, 'days').endOf('day');
368
+ }
369
+ };
370
+ }
371
+ },
372
+ {
373
+ regexp: /^(\d+)yearslater$/,
374
+ resolve: (__: any, _: string, years: string) => {
375
+ return {
376
+ label: __('DateRange.yearslater', {years}),
377
+ startDate: (now: moment.Moment) => {
378
+ return now.startOf('year');
379
+ },
380
+ endDate: (now: moment.Moment) => {
381
+ return now.startOf('year').add(years, 'years').endOf('day');
382
+ }
383
+ };
384
+ }
385
+ }
386
+ ];
387
+
206
388
  export class DateRangePicker extends React.Component<
207
389
  DateRangePickerProps,
208
390
  DateRangePickerState
@@ -280,6 +462,8 @@ export class DateRangePicker extends React.Component<
280
462
  this.open = this.open.bind(this);
281
463
  this.close = this.close.bind(this);
282
464
  this.handleSelectChange = this.handleSelectChange.bind(this);
465
+ this.handleTimeStartChange = this.handleTimeStartChange.bind(this);
466
+ this.handleTimeEndChange = this.handleTimeEndChange.bind(this);
283
467
  this.handleFocus = this.handleFocus.bind(this);
284
468
  this.handleBlur = this.handleBlur.bind(this);
285
469
  this.checkStartIsValidDate = this.checkStartIsValidDate.bind(this);
@@ -479,6 +663,88 @@ export class DateRangePicker extends React.Component<
479
663
  this.isFirstClick = !this.isFirstClick;
480
664
  }
481
665
 
666
+ // 主要用于处理时间的情况
667
+ handleTimeStartChange(newValue: moment.Moment) {
668
+ const {embed, timeFormat, minDuration, maxDuration, minDate} = this.props;
669
+ const {startDate, endDate} = this.state;
670
+
671
+ if (
672
+ startDate &&
673
+ (!endDate || (endDate && newValue.isSame(startDate))) && // 没有结束时间,或者新的时间也是开始时间,这时都会将新值当成结束时间
674
+ newValue.isSameOrAfter(startDate) &&
675
+ (!minDuration || newValue.isAfter(startDate.clone().add(minDuration))) &&
676
+ (!maxDuration || newValue.isBefore(startDate.clone().add(maxDuration)))
677
+ ) {
678
+ return this.setState(
679
+ {
680
+ endDate: this.filterDate(newValue, endDate, timeFormat, 'end')
681
+ },
682
+ () => {
683
+ embed && this.confirm();
684
+ }
685
+ );
686
+ }
687
+
688
+ if (minDate && newValue && newValue.isBefore(minDate, 'second')) {
689
+ newValue = minDate;
690
+ }
691
+
692
+ this.setState(
693
+ {
694
+ startDate: this.filterDate(
695
+ newValue,
696
+ startDate || minDate,
697
+ timeFormat,
698
+ 'start'
699
+ )
700
+ },
701
+ () => {
702
+ embed && this.confirm();
703
+ }
704
+ );
705
+ }
706
+
707
+ handleTimeEndChange(newValue: moment.Moment) {
708
+ const {embed, timeFormat, minDuration, maxDuration, maxDate} = this.props;
709
+ const {startDate, endDate} = this.state;
710
+
711
+ if (
712
+ endDate &&
713
+ !startDate &&
714
+ newValue.isSameOrBefore(endDate) &&
715
+ (!minDuration ||
716
+ newValue.isBefore(endDate.clone().subtract(minDuration))) &&
717
+ (!maxDuration || newValue.isAfter(endDate.clone().subtract(maxDuration)))
718
+ ) {
719
+ return this.setState(
720
+ {
721
+ startDate: this.filterDate(newValue, startDate, timeFormat, 'start')
722
+ },
723
+ () => {
724
+ embed && this.confirm();
725
+ }
726
+ );
727
+ }
728
+
729
+ if (maxDate && newValue && newValue.isAfter(maxDate, 'second')) {
730
+ newValue = maxDate;
731
+ }
732
+
733
+ this.setState(
734
+ {
735
+ endDate: this.filterDate(
736
+ newValue,
737
+ endDate || maxDate,
738
+ timeFormat,
739
+ 'end'
740
+ )
741
+ },
742
+ () => {
743
+ embed && this.confirm();
744
+ }
745
+ );
746
+ }
747
+
482
748
  handleMobileChange(data: any, callback?: () => void) {
483
749
  this.setState(
484
750
  {
@@ -528,8 +794,20 @@ export class DateRangePicker extends React.Component<
528
794
  }
529
795
  let range: PlainObject = {};
530
796
  if (typeof item === 'string') {
531
- range = availableRanges[item];
532
- range.key = item;
797
+ if (availableRanges[item]) {
798
+ range = availableRanges[item];
799
+ range.key = item;
800
+ } else {
801
+ // 通过正则尝试匹配
802
+ for (let i = 0, len = advancedRanges.length; i < len; i++) {
803
+ let value = advancedRanges[i];
804
+ const m = value.regexp.exec(item);
805
+ if (m) {
806
+ range = value.resolve.apply(item, [__, ...m]);
807
+ range.key = item;
808
+ }
809
+ }
810
+ }
533
811
  } else if (
534
812
  (item as ShortCutDateRange).startDate &&
535
813
  (item as ShortCutDateRange).endDate
@@ -677,6 +955,7 @@ export class DateRangePicker extends React.Component<
677
955
  const __ = this.props.translate;
678
956
 
679
957
  const {startDate, endDate} = this.state;
958
+
680
959
  return (
681
960
  <div className={`${ns}DateRangePicker-wrap`}>
682
961
  {this.renderRanges(ranges)}
@@ -684,7 +963,13 @@ export class DateRangePicker extends React.Component<
684
963
  <Calendar
685
964
  className={`${ns}DateRangePicker-start`}
686
965
  value={startDate}
687
- onChange={this.handleSelectChange}
966
+ // 区分的原因是 time-range 左侧就只能选起始时间,而其它都能在左侧同时同时选择起始和结束
967
+ // TODO: 后续得把 time-range 代码拆分出来
968
+ onChange={
969
+ viewMode === 'time'
970
+ ? this.handleTimeStartChange
971
+ : this.handleSelectChange
972
+ }
688
973
  requiredConfirm={false}
689
974
  dateFormat={dateFormat}
690
975
  inputFormat={inputFormat}
@@ -701,7 +986,11 @@ export class DateRangePicker extends React.Component<
701
986
  <Calendar
702
987
  className={`${ns}DateRangePicker-end`}
703
988
  value={endDate}
704
- onChange={this.handleSelectChange}
989
+ onChange={
990
+ viewMode === 'time'
991
+ ? this.handleTimeEndChange
992
+ : this.handleSelectChange
993
+ }
705
994
  requiredConfirm={false}
706
995
  dateFormat={dateFormat}
707
996
  inputFormat={inputFormat}
@@ -21,11 +21,12 @@ import Button from './Button';
21
21
  import {value2array, OptionProps, Option} from './Select';
22
22
  import chunk from 'lodash/chunk';
23
23
  import {ClassNamesFn, themeable} from '../theme';
24
+ import {columnsSplit} from '../utils/columnsSplit';
24
25
 
25
26
  interface RadioProps extends OptionProps {
26
27
  id?: string;
27
28
  type: string;
28
- optionType?: string,
29
+ optionType?: string;
29
30
  value?: string;
30
31
  className?: string;
31
32
  style?: React.CSSProperties;
@@ -34,7 +35,7 @@ interface RadioProps extends OptionProps {
34
35
  btnActiveLevel?: string;
35
36
  disabled?: boolean;
36
37
  onChange?: Function;
37
- columnsCount: number;
38
+ columnsCount: number | number[];
38
39
  itemClassName?: string;
39
40
  labelField?: string;
40
41
  labelClassName?: string;
@@ -78,7 +79,7 @@ export class Radios extends React.Component<RadioProps, any> {
78
79
  }
79
80
 
80
81
  renderGroup(option: Option, index: number, valueArray: Array<Option>) {
81
- const {classnames: cx, optionType, classPrefix: ns,} = this.props;
82
+ const {classnames: cx, optionType, classPrefix: ns} = this.props;
82
83
 
83
84
  return (
84
85
  <div key={index} className={cx('RadiosControl-group', option.className)}>
@@ -178,20 +179,8 @@ export class Radios extends React.Component<RadioProps, any> {
178
179
  );
179
180
  }
180
181
 
181
- if (!inline && columnsCount > 1) {
182
- let weight = 12 / (columnsCount as number);
183
- let cellClassName = `Grid-col--sm${
184
- weight === Math.round(weight) ? weight : ''
185
- }`;
186
- body = chunk(body, columnsCount).map((group, groupIndex) => (
187
- <div className={cx('Grid')} key={groupIndex}>
188
- {Array.from({length: columnsCount as number}).map((_, index) => (
189
- <div key={index} className={cx(cellClassName)}>
190
- {group[index]}
191
- </div>
192
- ))}
193
- </div>
194
- ));
182
+ if (!inline) {
183
+ body = columnsSplit(body, cx, columnsCount);
195
184
  }
196
185
 
197
186
  return (