amis 1.4.2-beta.12 → 1.4.2-beta.17

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 (179) hide show
  1. package/lib/Schema.d.ts +4 -3
  2. package/lib/Schema.js.map +1 -1
  3. package/lib/components/AssociatedSelection.js +2 -2
  4. package/lib/components/AssociatedSelection.js.map +2 -2
  5. package/lib/components/Checkbox.d.ts +20 -20
  6. package/lib/components/Collapse.d.ts +51 -23
  7. package/lib/components/Collapse.js +69 -11
  8. package/lib/components/Collapse.js.map +2 -2
  9. package/lib/components/CollapseGroup.d.ts +88 -0
  10. package/lib/components/CollapseGroup.js +81 -0
  11. package/lib/components/CollapseGroup.js.map +13 -0
  12. package/lib/components/Editor.d.ts +84 -84
  13. package/lib/components/GridNav.d.ts +52 -0
  14. package/lib/components/GridNav.js +123 -0
  15. package/lib/components/GridNav.js.map +13 -0
  16. package/lib/components/InputBox.d.ts +22 -21
  17. package/lib/components/InputBox.js +10 -2
  18. package/lib/components/InputBox.js.map +2 -2
  19. package/lib/components/ListGroup.d.ts +21 -21
  20. package/lib/components/ResultBox.d.ts +84 -84
  21. package/lib/components/ResultBox.js +10 -2
  22. package/lib/components/ResultBox.js.map +2 -2
  23. package/lib/components/Tabs.d.ts +20 -20
  24. package/lib/components/TabsTransfer.d.ts +84 -84
  25. package/lib/components/Toast.d.ts +86 -85
  26. package/lib/components/Toast.js +6 -3
  27. package/lib/components/Toast.js.map +2 -2
  28. package/lib/components/Transfer.d.ts +84 -84
  29. package/lib/components/TransferDropDown.d.ts +85 -84
  30. package/lib/components/TransferDropDown.js +2 -2
  31. package/lib/components/TransferDropDown.js.map +2 -2
  32. package/lib/components/TransferPicker.d.ts +4 -0
  33. package/lib/components/TransferPicker.js +2 -2
  34. package/lib/components/TransferPicker.js.map +2 -2
  35. package/lib/components/Tree.d.ts +115 -84
  36. package/lib/components/Tree.js +183 -30
  37. package/lib/components/Tree.js.map +2 -2
  38. package/lib/components/icons.js +2 -0
  39. package/lib/components/icons.js.map +2 -2
  40. package/lib/envOverwrite.d.ts +1 -1
  41. package/lib/envOverwrite.js +24 -9
  42. package/lib/envOverwrite.js.map +2 -2
  43. package/lib/factory.d.ts +11 -1
  44. package/lib/factory.js +31 -4
  45. package/lib/factory.js.map +2 -2
  46. package/lib/icons/download.js +7 -0
  47. package/lib/icons/drag-bar.js +10 -3
  48. package/lib/index.d.ts +2 -0
  49. package/lib/index.js +3 -1
  50. package/lib/index.js.map +2 -2
  51. package/lib/locale/en-US.js +1 -0
  52. package/lib/locale/en-US.js.map +2 -2
  53. package/lib/locale/zh-CN.js +1 -0
  54. package/lib/locale/zh-CN.js.map +2 -2
  55. package/lib/renderers/Collapse.d.ts +25 -20
  56. package/lib/renderers/Collapse.js +10 -73
  57. package/lib/renderers/Collapse.js.map +2 -2
  58. package/lib/renderers/CollapseGroup.d.ts +42 -0
  59. package/lib/renderers/CollapseGroup.js +33 -0
  60. package/lib/renderers/CollapseGroup.js.map +13 -0
  61. package/lib/renderers/Form/InputCity.d.ts +84 -84
  62. package/lib/renderers/Form/InputFile.d.ts +6 -0
  63. package/lib/renderers/Form/InputFile.js +18 -4
  64. package/lib/renderers/Form/InputFile.js.map +2 -2
  65. package/lib/renderers/Form/Item.js +2 -1
  66. package/lib/renderers/Form/Item.js.map +2 -2
  67. package/lib/renderers/Form/Select.d.ts +1 -0
  68. package/lib/renderers/Form/Select.js +2 -2
  69. package/lib/renderers/Form/Select.js.map +2 -2
  70. package/lib/renderers/Form/TransferPicker.d.ts +4 -0
  71. package/lib/renderers/Form/TransferPicker.js +2 -2
  72. package/lib/renderers/Form/TransferPicker.js.map +2 -2
  73. package/lib/renderers/Form/index.js +1 -1
  74. package/lib/renderers/Form/index.js.map +2 -2
  75. package/lib/renderers/GridNav.d.ts +99 -0
  76. package/lib/renderers/GridNav.js +82 -0
  77. package/lib/renderers/GridNav.js.map +13 -0
  78. package/lib/store/formItem.js +60 -4
  79. package/lib/store/formItem.js.map +2 -2
  80. package/lib/store/table.js +5 -5
  81. package/lib/store/table.js.map +2 -2
  82. package/lib/themes/ang-ie11.css +224 -31
  83. package/lib/themes/ang.css +224 -31
  84. package/lib/themes/ang.css.map +1 -1
  85. package/lib/themes/antd-ie11.css +224 -31
  86. package/lib/themes/antd.css +224 -31
  87. package/lib/themes/antd.css.map +1 -1
  88. package/lib/themes/cxd-ie11.css +231 -38
  89. package/lib/themes/cxd.css +231 -38
  90. package/lib/themes/cxd.css.map +1 -1
  91. package/lib/themes/dark-ie11.css +224 -31
  92. package/lib/themes/dark.css +224 -31
  93. package/lib/themes/dark.css.map +1 -1
  94. package/lib/themes/default.css +231 -38
  95. package/lib/themes/default.css.map +1 -1
  96. package/lib/types.d.ts +1 -1
  97. package/lib/types.js.map +1 -1
  98. package/lib/utils/api.d.ts +1 -0
  99. package/lib/utils/api.js +77 -6
  100. package/lib/utils/api.js.map +2 -2
  101. package/lib/utils/helper.d.ts +6 -0
  102. package/lib/utils/helper.js +18 -1
  103. package/lib/utils/helper.js.map +2 -2
  104. package/package.json +1 -1
  105. package/schema.json +278 -48
  106. package/scss/base/_common.scss +3 -0
  107. package/scss/components/_anchor-nav.scss +1 -0
  108. package/scss/components/_collapse-group.scss +11 -0
  109. package/scss/components/_collapse.scss +33 -22
  110. package/scss/components/_grid-nav.scss +128 -0
  111. package/scss/components/_input-box.scss +1 -0
  112. package/scss/components/_nav.scss +1 -1
  113. package/scss/components/_picker-columns.scss +1 -0
  114. package/scss/components/_popover.scss +0 -4
  115. package/scss/components/_result-box.scss +1 -0
  116. package/scss/components/_spinner.scss +5 -4
  117. package/scss/components/_table.scss +6 -0
  118. package/scss/components/form/_combo.scss +4 -0
  119. package/scss/components/form/_file.scss +11 -0
  120. package/scss/components/form/_tree.scss +42 -0
  121. package/scss/themes/_common.scss +3 -0
  122. package/scss/themes/_cxd-variables.scss +6 -7
  123. package/scss/themes/cxd.scss +1 -0
  124. package/sdk/ang-ie11.css +268 -32
  125. package/sdk/ang.css +263 -31
  126. package/sdk/antd-ie11.css +268 -32
  127. package/sdk/antd.css +263 -31
  128. package/sdk/charts.js +15 -15
  129. package/sdk/color-picker.js +65 -65
  130. package/sdk/cropperjs.js +2 -2
  131. package/sdk/cxd-ie11.css +274 -36
  132. package/sdk/cxd.css +270 -38
  133. package/sdk/dark-ie11.css +268 -32
  134. package/sdk/dark.css +263 -31
  135. package/sdk/exceljs.js +1 -1
  136. package/sdk/markdown.js +69 -69
  137. package/sdk/papaparse.js +1 -1
  138. package/sdk/renderers/Form/CityDB.js +1 -1
  139. package/sdk/rest.js +18 -18
  140. package/sdk/rich-text.js +62 -62
  141. package/sdk/sdk-ie11.css +274 -36
  142. package/sdk/sdk.css +270 -38
  143. package/sdk/sdk.js +1179 -1143
  144. package/sdk/thirds/hls.js/hls.js +1 -1
  145. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  146. package/sdk/tinymce.js +57 -57
  147. package/src/Schema.ts +5 -1
  148. package/src/components/AssociatedSelection.tsx +3 -1
  149. package/src/components/Collapse.tsx +144 -20
  150. package/src/components/CollapseGroup.tsx +130 -0
  151. package/src/components/GridNav.tsx +233 -0
  152. package/src/components/InputBox.tsx +10 -9
  153. package/src/components/ResultBox.tsx +9 -9
  154. package/src/components/Toast.tsx +23 -16
  155. package/src/components/TransferDropDown.tsx +4 -1
  156. package/src/components/TransferPicker.tsx +7 -0
  157. package/src/components/Tree.tsx +194 -8
  158. package/src/components/icons.tsx +2 -0
  159. package/src/envOverwrite.ts +20 -7
  160. package/src/factory.tsx +52 -6
  161. package/src/icons/download.svg +4 -0
  162. package/src/icons/drag-bar.svg +12 -6
  163. package/src/index.tsx +2 -0
  164. package/src/locale/en-US.ts +1 -0
  165. package/src/locale/zh-CN.ts +1 -0
  166. package/src/renderers/Collapse.tsx +70 -117
  167. package/src/renderers/CollapseGroup.tsx +80 -0
  168. package/src/renderers/Form/InputFile.tsx +36 -4
  169. package/src/renderers/Form/Item.tsx +2 -1
  170. package/src/renderers/Form/Select.tsx +6 -2
  171. package/src/renderers/Form/TransferPicker.tsx +7 -1
  172. package/src/renderers/Form/index.tsx +1 -2
  173. package/src/renderers/GridNav.tsx +204 -0
  174. package/src/store/formItem.ts +116 -3
  175. package/src/store/table.ts +9 -5
  176. package/src/types.ts +1 -1
  177. package/src/utils/api.ts +93 -6
  178. package/src/utils/helper.ts +19 -0
  179. package/tsconfig-for-declaration.json +1 -1
package/src/Schema.ts CHANGED
@@ -12,6 +12,7 @@ import {FormSchema} from './renderers/Form';
12
12
  import {CarouselSchema} from './renderers/Carousel';
13
13
  import {ChartSchema} from './renderers/Chart';
14
14
  import {CollapseSchema} from './renderers/Collapse';
15
+ import {CollapseGroupSchema} from './renderers/CollapseGroup';
15
16
  import {ColorSchema} from './renderers/Color';
16
17
  import {ContainerSchema} from './renderers/Container';
17
18
  import {CRUDSchema} from './renderers/CRUD';
@@ -131,6 +132,7 @@ export type SchemaType =
131
132
  | 'carousel'
132
133
  | 'chart'
133
134
  | 'collapse'
135
+ | 'collapse-group'
134
136
  | 'color'
135
137
  | 'container'
136
138
  | 'crud'
@@ -317,6 +319,7 @@ export type SchemaType =
317
319
  | 'tree-select'
318
320
  | 'table-view'
319
321
  | 'portlet'
322
+ | 'grid-nav'
320
323
 
321
324
  // 原生 input 类型
322
325
  | 'native-date'
@@ -339,6 +342,7 @@ export type SchemaObject =
339
342
  | CarouselSchema
340
343
  | ChartSchema
341
344
  | CollapseSchema
345
+ | CollapseGroupSchema
342
346
  | ColorSchema
343
347
  | ContainerSchema
344
348
  | CRUDSchema
@@ -487,7 +491,7 @@ export interface SchemaApiObject {
487
491
  /**
488
492
  * API 发送类型
489
493
  */
490
- method?: 'get' | 'post' | 'put' | 'delete' | 'patch';
494
+ method?: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'jsonp';
491
495
 
492
496
  /**
493
497
  * API 发送目标地址
@@ -105,7 +105,8 @@ export class AssociatedSelection extends BaseSelection<
105
105
  disabled,
106
106
  leftMode,
107
107
  cellRender,
108
- multiple
108
+ multiple,
109
+ onDeferLoad
109
110
  } = this.props;
110
111
 
111
112
  const selectdOption = BaseSelection.resolveSelected(
@@ -127,6 +128,7 @@ export class AssociatedSelection extends BaseSelection<
127
128
  onChange={this.handleLeftSelect}
128
129
  multiple={false}
129
130
  clearable={false}
131
+ onDeferLoad={onDeferLoad}
130
132
  />
131
133
  ) : (
132
134
  <GroupedSelecton
@@ -12,6 +12,8 @@ import Transition, {
12
12
  EXITING
13
13
  } from 'react-transition-group/Transition';
14
14
  import {autobind} from '../utils/helper';
15
+ import {isClickOnInput} from '../utils/helper';
16
+ import {TranslateFn} from '../locale';
15
17
 
16
18
  const collapseStyles: {
17
19
  [propName: string]: string;
@@ -22,24 +24,87 @@ const collapseStyles: {
22
24
  };
23
25
 
24
26
  export interface CollapseProps {
25
- show?: boolean;
27
+ key?: string;
28
+ id?: string;
26
29
  mountOnEnter?: boolean;
27
30
  unmountOnExit?: boolean;
28
31
  className?: string;
29
32
  classPrefix: string;
30
33
  classnames: ClassNamesFn;
34
+ headerPosition?: 'top' | 'bottom';
35
+ header?: React.ReactElement;
36
+ body: any;
37
+ bodyClassName?: string;
38
+ disabled?: boolean;
39
+ collapsable?: boolean;
40
+ collapsed?: boolean;
41
+ showArrow?: boolean;
42
+ expandIcon?: React.ReactElement | null;
43
+ headingClassName?: string;
44
+ collapseHeader?: React.ReactElement | null;
45
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'base';
46
+ onCollapse?: (item: any, collapsed: boolean) => void;
47
+ wrapperComponent?: any;
48
+ headingComponent?: any;
49
+ translate?: TranslateFn;
50
+ propsUpdate?: boolean;
31
51
  }
32
52
 
33
- export class Collapse extends React.Component<CollapseProps, any> {
34
- static defaultProps: Pick<
35
- CollapseProps,
36
- 'show' | 'mountOnEnter' | 'unmountOnExit'
37
- > = {
38
- show: false,
53
+ export interface CollapseState {
54
+ collapsed: boolean;
55
+ }
56
+
57
+ export class Collapse extends React.Component<CollapseProps, CollapseState> {
58
+
59
+ static defaultProps: Partial<CollapseProps> = {
39
60
  mountOnEnter: false,
40
- unmountOnExit: false
61
+ unmountOnExit: false,
62
+ headerPosition: 'top',
63
+ wrapperComponent: 'div',
64
+ headingComponent: 'div',
65
+ className: '',
66
+ headingClassName: '',
67
+ bodyClassName: '',
68
+ collapsable: true,
69
+ disabled: false,
70
+ showArrow: true,
71
+ propsUpdate: false
72
+ };
73
+
74
+ state: CollapseState = {
75
+ collapsed: false
41
76
  };
42
77
 
78
+ constructor(props: CollapseProps) {
79
+ super(props);
80
+
81
+ this.toggleCollapsed = this.toggleCollapsed.bind(this);
82
+ this.state.collapsed = !!props.collapsed;
83
+ }
84
+
85
+ static getDerivedStateFromProps(nextProps: CollapseProps, preState: CollapseState) {
86
+ if (nextProps.propsUpdate && nextProps.collapsed !== preState.collapsed) {
87
+ return {
88
+ collapsed: !!nextProps.collapsed
89
+ };
90
+ }
91
+ return null;
92
+ }
93
+
94
+ toggleCollapsed(e: React.MouseEvent<HTMLElement>) {
95
+ if (isClickOnInput(e)) {
96
+ return;
97
+ }
98
+ const props = this.props;
99
+ if (props.disabled || props.collapsable === false) {
100
+ return;
101
+ }
102
+ props.onCollapse && props.onCollapse(props, !this.state.collapsed);
103
+ this.setState({
104
+ collapsed: !this.state.collapsed
105
+ });
106
+ }
107
+
43
108
  contentDom: any;
44
109
  contentRef = (ref: any) => (this.contentDom = ref);
45
110
 
@@ -77,18 +142,53 @@ export class Collapse extends React.Component<CollapseProps, any> {
77
142
 
78
143
  render() {
79
144
  const {
80
- show,
81
- children,
82
145
  classnames: cx,
83
146
  mountOnEnter,
84
- unmountOnExit
147
+ unmountOnExit,
148
+ classPrefix: ns,
149
+ size,
150
+ wrapperComponent: WrapperComponent,
151
+ headingComponent: HeadingComponent,
152
+ className,
153
+ headingClassName,
154
+ headerPosition,
155
+ collapseHeader,
156
+ header,
157
+ body,
158
+ bodyClassName,
159
+ collapsable,
160
+ translate: __,
161
+ showArrow,
162
+ expandIcon,
163
+ disabled
85
164
  } = this.props;
86
165
 
87
- return (
166
+ const finalHeader = this.state.collapsed ? header : collapseHeader || header;
167
+
168
+ let dom = [
169
+ finalHeader ? (
170
+ <HeadingComponent
171
+ key="header"
172
+ onClick={this.toggleCollapsed}
173
+ className={cx(`Collapse-header`, headingClassName)}
174
+ >
175
+ {showArrow && collapsable
176
+ ? expandIcon
177
+ ? React.cloneElement(expandIcon, {
178
+ ...expandIcon.props,
179
+ className: cx('Collapse-icon-tranform')
180
+ })
181
+ : <span className={cx('Collapse-arrow')} />
182
+ : ''}
183
+ {finalHeader}
184
+ </HeadingComponent>
185
+ ) : null,
186
+
88
187
  <Transition
188
+ key="body"
89
189
  mountOnEnter={mountOnEnter}
90
190
  unmountOnExit={unmountOnExit}
91
- in={show}
191
+ in={!this.state.collapsed}
92
192
  timeout={300}
93
193
  onEnter={this.handleEnter}
94
194
  onEntering={this.handleEntering}
@@ -105,17 +205,41 @@ export class Collapse extends React.Component<CollapseProps, any> {
105
205
  className={cx('Collapse-contentWrapper', collapseStyles[status])}
106
206
  ref={this.contentRef}
107
207
  >
108
- {React.cloneElement(children as any, {
109
- ...(children as React.ReactElement).props,
110
- className: cx(
111
- 'Collapse-content',
112
- (children as React.ReactElement).props.className
113
- )
114
- })}
208
+ <div className={cx('Collapse-body', bodyClassName)}>
209
+ {React.cloneElement(body as any, {
210
+ ...(body as React.ReactElement).props,
211
+ className: cx(
212
+ 'Collapse-content',
213
+ (body as React.ReactElement).props.className
214
+ )
215
+ })}
216
+ </div>
115
217
  </div>
116
218
  );
117
219
  }}
118
220
  </Transition>
221
+
222
+ ];
223
+
224
+ if (headerPosition === 'bottom') {
225
+ dom.reverse();
226
+ }
227
+
228
+ return (
229
+ <WrapperComponent
230
+ className={cx(
231
+ `Collapse`,
232
+ {
233
+ 'is-active': !this.state.collapsed,
234
+ [`Collapse--${size}`]: size,
235
+ 'Collapse--disabled': disabled || collapsable === false,
236
+ 'Collapse--title-bottom': headerPosition === 'bottom'
237
+ },
238
+ className
239
+ )}
240
+ >
241
+ {dom}
242
+ </WrapperComponent>
119
243
  );
120
244
  }
121
245
  }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @file CollapseGroup
3
+ * @description 折叠面板group
4
+ * @author hongyang03
5
+ */
6
+
7
+ import React from 'react';
8
+ import {CollapseProps} from '../renderers/Collapse';
9
+ import {SchemaNode} from '../types';
10
+ import {ClassNamesFn, themeable} from '../theme';
11
+
12
+ export interface CollapseGroupProps {
13
+ defaultActiveKey?: Array<string | number | never> | string | number;
14
+ accordion?: boolean;
15
+ expandIcon?: SchemaNode;
16
+ expandIconPosition?: 'left' | 'right';
17
+ body?: Array<React.ReactElement>;
18
+ className?: string;
19
+ classnames: ClassNamesFn;
20
+ classPrefix: string;
21
+ }
22
+
23
+ export interface CollapseGroupState {
24
+ activeKey: Array<string | number | never>;
25
+ }
26
+
27
+ class CollapseGroup extends React.Component<
28
+ CollapseGroupProps,
29
+ CollapseGroupState
30
+ > {
31
+
32
+ static defaultProps: Partial<CollapseGroupProps> = {
33
+ className: '',
34
+ accordion: false,
35
+ expandIconPosition: 'left'
36
+ };
37
+
38
+ constructor(props: CollapseGroupProps) {
39
+ super(props);
40
+
41
+ // 传入的activeKey会被自动转换为defaultActiveKey
42
+ let activeKey = props.defaultActiveKey;
43
+ if (!Array.isArray(activeKey)) {
44
+ activeKey = activeKey ? [activeKey] : [];
45
+ }
46
+ if (props.accordion) {
47
+ // 手风琴模式下只展开第一个元素
48
+ activeKey = activeKey.length ? [activeKey[0]] : [];
49
+ }
50
+
51
+ this.state = {
52
+ activeKey: activeKey.map((key: number | string) => String(key))
53
+ };
54
+ }
55
+
56
+ collapseChange(item: CollapseProps, collapsed: boolean) {
57
+ let activeKey = this.state.activeKey;
58
+ if (collapsed) {
59
+ if (this.props.accordion) {
60
+ activeKey = [];
61
+ }
62
+ else {
63
+ for(let i = 0; i < activeKey.length; i++) {
64
+ if (activeKey[i] === item.id) {
65
+ activeKey.splice(i, 1);
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ else {
72
+ if (this.props.accordion) {
73
+ activeKey = [item.id];
74
+ }
75
+ else {
76
+ activeKey.push(item.id);
77
+ }
78
+ }
79
+ this.setState({
80
+ activeKey
81
+ });
82
+ }
83
+
84
+ getItems = (children: React.ReactNode) => {
85
+ if (!Array.isArray(children)) {
86
+ return children;
87
+ }
88
+
89
+ return children.map((child: React.ReactElement, index: number) => {
90
+ let props = child.props;
91
+ const id = props.schema.key || String(index);
92
+ const collapsed = this.state.activeKey.indexOf(id) === -1;
93
+
94
+ return React.cloneElement(child as any, {
95
+ ...props,
96
+ key: id,
97
+ id,
98
+ collapsed,
99
+ expandIcon: this.props.expandIcon,
100
+ propsUpdate: true,
101
+ onCollapse: (item: CollapseProps, collapsed: boolean) => this.collapseChange(item, collapsed)
102
+ });
103
+ });
104
+ };
105
+
106
+ render() {
107
+ const {
108
+ classnames: cx,
109
+ className,
110
+ expandIconPosition,
111
+ children
112
+ } = this.props;
113
+
114
+ return (
115
+ <div
116
+ className={cx(
117
+ `CollapseGroup`,
118
+ {
119
+ 'icon-position-right': expandIconPosition === 'right',
120
+ },
121
+ className
122
+ )}
123
+ >
124
+ {this.getItems(children)}
125
+ </div>
126
+ );
127
+ }
128
+ }
129
+
130
+ export default themeable(CollapseGroup);
@@ -0,0 +1,233 @@
1
+ /**
2
+ * @file GridNav
3
+ * @description 金刚位宫格导航 参考react-vant
4
+ */
5
+
6
+ import React, {useMemo} from 'react';
7
+ import {ClassNamesFn} from '../theme';
8
+ import {Badge, BadgeProps} from './Badge';
9
+
10
+ export type GridNavDirection = 'horizontal' | 'vertical';
11
+
12
+ export interface GridNavProps {
13
+ /** 是否将格子固定为正方形 */
14
+ square?: boolean;
15
+ /** 是否将格子内容居中显示 */
16
+ center?: boolean;
17
+ /** 是否显示边框 */
18
+ border?: boolean;
19
+ /** 格子之间的间距,默认单位为`px` */
20
+ gutter?: number;
21
+ /** 是否调换图标和文本的位置 */
22
+ reverse?: boolean;
23
+ /** 图标占比,默认单位为`%` */
24
+ iconRatio?: number;
25
+ /** 格子内容排列的方向,可选值为 `horizontal` */
26
+ direction?: GridNavDirection;
27
+ /** 列数 */
28
+ columnNum?: number;
29
+ className?: string;
30
+ itemClassName?: string;
31
+ classnames: ClassNamesFn;
32
+ style?: React.CSSProperties;
33
+ }
34
+
35
+ export interface GridNavItemProps {
36
+ /** 图标右上角徽标 */
37
+ badge?: BadgeProps;
38
+ /** 文字 */
39
+ text?: string | React.ReactNode;
40
+ /** 图标名称或图片链接 */
41
+ icon?: string | React.ReactNode;
42
+ className?: string;
43
+ style?: React.CSSProperties;
44
+ contentClassName?: string;
45
+ contentStyle?: React.CSSProperties;
46
+ children?: React.ReactNode;
47
+ classnames: ClassNamesFn;
48
+ onClick?: (event: React.MouseEvent) => void;
49
+ }
50
+
51
+ type InternalProps = {
52
+ parent?: GridNavProps;
53
+ index?: number;
54
+ };
55
+
56
+ function addUnit(value?: string | number): string | undefined {
57
+ if (value === undefined || value === null) {
58
+ return undefined;
59
+ }
60
+ value = String(value);
61
+ return /^\d+(\.\d+)?$/.test(value) ? `${value}px` : value;
62
+ }
63
+
64
+ export const GridNavItem: React.FC<GridNavItemProps & InternalProps> = ({
65
+ children,
66
+ classnames: cx,
67
+ className,
68
+ style,
69
+ ...props
70
+ }) => {
71
+ const {index = 0, parent} = props;
72
+ if (!parent) {
73
+ if (process.env.NODE_ENV !== 'production') {
74
+ // eslint-disable-next-line no-console
75
+ console.error(
76
+ '[React Vant] <GridNavItem> must be a child component of <GridNav>.'
77
+ );
78
+ }
79
+ return null;
80
+ }
81
+
82
+ const rootStyle = useMemo(() => {
83
+ const {square, gutter, columnNum = 4} = parent;
84
+ const percent = `${100 / +columnNum}%`;
85
+ const internalStyle: React.CSSProperties = {
86
+ ...style,
87
+ flexBasis: percent
88
+ };
89
+
90
+ if (square) {
91
+ internalStyle.paddingTop = percent;
92
+ } else if (gutter) {
93
+ const gutterValue = addUnit(gutter);
94
+ internalStyle.paddingRight = gutterValue;
95
+
96
+ if (index >= columnNum) {
97
+ internalStyle.marginTop = gutterValue;
98
+ }
99
+ }
100
+
101
+ return internalStyle;
102
+ }, [parent.style, parent.gutter, parent.columnNum]);
103
+
104
+ const contentStyle = useMemo(() => {
105
+ const {square, gutter} = parent;
106
+
107
+ if (square && gutter) {
108
+ const gutterValue = addUnit(gutter);
109
+ return {
110
+ ...props.contentStyle,
111
+ right: gutterValue,
112
+ bottom: gutterValue,
113
+ height: 'auto'
114
+ };
115
+ }
116
+ return props.contentStyle;
117
+ }, [parent.gutter, parent.columnNum, props.contentStyle]);
118
+
119
+ const renderIcon = () => {
120
+ const ratio = parent.iconRatio || 60;
121
+ if (typeof props.icon === 'string') {
122
+ if (props.badge) {
123
+ return (
124
+ <Badge {...props.badge}>
125
+ <div className={cx('GridNavItem-image')}>
126
+ <img src={props.icon} style={{width: ratio + '%'}} />
127
+ </div>
128
+ </Badge>
129
+ );
130
+ }
131
+ return (
132
+ <div className={cx('GridNavItem-image')}>
133
+ <img src={props.icon} style={{width: ratio + '%'}} />
134
+ </div>
135
+ );
136
+ }
137
+
138
+ if (React.isValidElement(props.icon)) {
139
+ return <Badge {...(props.badge as BadgeProps)}>{props.icon}</Badge>;
140
+ }
141
+
142
+ return null;
143
+ };
144
+
145
+ const renderText = () => {
146
+ if (React.isValidElement(props.text)) {
147
+ return props.text;
148
+ }
149
+ if (props.text) {
150
+ return <span className={cx('GridNavItem-text')}>{props.text}</span>;
151
+ }
152
+ return null;
153
+ };
154
+
155
+ const renderContent = () => {
156
+ if (children) {
157
+ return children;
158
+ }
159
+ return (
160
+ <>
161
+ {renderIcon()}
162
+ {renderText()}
163
+ </>
164
+ );
165
+ };
166
+
167
+ const {center, border, square, gutter, reverse, direction} = parent;
168
+
169
+ const prefix = 'GridNavItem-content';
170
+ const classes = cx(`${prefix} ${props.contentClassName || ''}`, {
171
+ [`${prefix}--${direction}`]: !!direction,
172
+ [`${prefix}--center`]: center,
173
+ [`${prefix}--square`]: square,
174
+ [`${prefix}--reverse`]: reverse,
175
+ [`${prefix}--clickable`]: !!props.onClick,
176
+ [`${prefix}--surround`]: border && gutter,
177
+ [`${prefix}--border u-hairline`]: border
178
+ });
179
+
180
+ return (
181
+ <div
182
+ className={cx(className, {'GridNavItem--square': square})}
183
+ style={rootStyle}
184
+ >
185
+ <div
186
+ role={props.onClick ? 'button' : undefined}
187
+ className={classes}
188
+ style={contentStyle}
189
+ onClick={props.onClick}
190
+ >
191
+ {renderContent()}
192
+ </div>
193
+ </div>
194
+ );
195
+ };
196
+
197
+ const GridNav: React.FC<GridNavProps> = ({
198
+ children,
199
+ className,
200
+ classnames: cx,
201
+ itemClassName,
202
+ style,
203
+ ...props
204
+ }) => {
205
+ return (
206
+ <div
207
+ style={{paddingLeft: addUnit(props.gutter), ...style}}
208
+ className={cx(`GridNav ${className || ''}`, {
209
+ 'GridNav-top u-hairline': props.border && !props.gutter
210
+ })}
211
+ >
212
+ {React.Children.toArray(children)
213
+ .filter(Boolean)
214
+ .map((child: React.ReactElement, index: number) =>
215
+ React.cloneElement(child, {
216
+ index,
217
+ parent: props,
218
+ className: itemClassName,
219
+ classnames: cx
220
+ })
221
+ )}
222
+ </div>
223
+ );
224
+ };
225
+
226
+ GridNav.defaultProps = {
227
+ direction: 'vertical',
228
+ center: true,
229
+ border: true,
230
+ columnNum: 4
231
+ };
232
+
233
+ export default GridNav;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import {ThemeProps, themeable} from '../theme';
3
3
  import Input from './Input';
4
- import {autobind} from '../utils/helper';
4
+ import {autobind, ucFirst} from '../utils/helper';
5
5
  import {Icon} from './icons';
6
6
 
7
7
  export interface InputBoxProps
@@ -17,6 +17,7 @@ export interface InputBoxProps
17
17
  placeholder?: string;
18
18
  prefix?: JSX.Element;
19
19
  children?: JSX.Element;
20
+ borderMode?: 'full' | 'half' | 'none';
20
21
  }
21
22
 
22
23
  export interface InputBoxState {
@@ -79,20 +80,20 @@ export class InputBox extends React.Component<InputBoxProps, InputBoxState> {
79
80
  placeholder,
80
81
  prefix: result,
81
82
  children,
83
+ borderMode,
82
84
  ...rest
83
85
  } = this.props;
84
86
  const isFocused = this.state.isFocused;
85
87
 
86
88
  return (
87
89
  <div
88
- className={cx(
89
- 'InputBox',
90
- className,
91
- isFocused ? 'is-focused' : '',
92
- disabled ? 'is-disabled' : '',
93
- hasError ? 'is-error' : '',
94
- rest.onClick ? 'is-clickable' : ''
95
- )}
90
+ className={cx('InputBox', className, {
91
+ 'is-focused': isFocused,
92
+ 'is-disabled': disabled,
93
+ 'is-error': hasError,
94
+ 'is-clickable': rest.onClick,
95
+ [`InputBox--border${ucFirst(borderMode)}`]: borderMode
96
+ })}
96
97
  >
97
98
  {result}
98
99