Skip to content

Commit 285c428

Browse files
committed
添加modal/drawer功能
1 parent 362d526 commit 285c428

File tree

9 files changed

+266
-22
lines changed

9 files changed

+266
-22
lines changed

atom.css

+1
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,4 @@
371371

372372
.fr-wrapper .truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
373373
.fr-wrapper .bg-white { background-color: #fff; }
374+
.fr-wrapper .pointer:hover { cursor: pointer; }

src/base/asField.jsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,14 @@ export const asField = ({ FieldUI, Widget }) => {
9191
if (isDependShow({ formData, dependShow })) {
9292
return null;
9393
}
94-
const isComplex =
94+
95+
let isComplex =
9596
_schema.type === 'object' ||
9697
(_schema.type === 'array' && _schema.enum === undefined);
98+
const isModal = options && (options.modal || options.drawer);
99+
if (isModal) {
100+
isComplex = false;
101+
}
97102

98103
const validateText = getValidateText(_rest);
99104
// 必填*,label,描述,竖排时的校验语,只要存在一个,label就不为空
@@ -179,15 +184,18 @@ export const DefaultFieldUI = ({
179184
enum: _enum,
180185
description = '',
181186
'ui:widget': widget,
187+
'ui:options': options,
182188
} = schema;
183189
const isCheckbox = type === 'boolean' && widget !== 'switch';
184-
190+
const isModal = options && (options.modal || options.drawer);
185191
let fieldClass = `fr-field w-100 ${isComplex ? 'fr-field-complex' : ''}`;
186192
let labelClass = 'fr-label mb2';
187193
let contentClass = 'fr-content';
188-
189194
switch (type) {
190195
case 'object':
196+
if (isModal) {
197+
break;
198+
}
191199
if (title) {
192200
labelClass += ' fr-label-object bb b--black-20 pb1 mt2 mb3'; // fr-label-object 无默认style,只是占位用于使用者样式覆盖
193201
}
@@ -199,6 +207,9 @@ export const DefaultFieldUI = ({
199207
}
200208
break;
201209
case 'array':
210+
if (isModal) {
211+
break;
212+
}
202213
if (title && !_enum) {
203214
labelClass += ' fr-label-array mt2 mb3';
204215
}

src/base/utils.js

+7
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,10 @@ export function isFunctionSchema(schema) {
207207
}
208208
});
209209
}
210+
211+
function stringContains(str, text) {
212+
return str.indexOf(text) > -1;
213+
}
214+
215+
export const isObj = a =>
216+
stringContains(Object.prototype.toString.call(a), 'Object');

src/components/listHoc.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ const fieldListHoc = ButtonComponent => {
188188
/>
189189
))}
190190
{!readonly && (
191-
<div className="tr">
191+
<div className="tr mb2">
192192
{canAdd && (
193193
<ButtonComponent icon="add" onClick={this.handleAddClick}>
194194
新增

src/components/map.jsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import React from 'react';
22

33
export default function map(p) {
4+
let className = 'fr-map ';
5+
const { options = {} } = p || {};
6+
const isModal = options.modal || options.drawer;
7+
try {
8+
className += isModal ? 'fr-wrapper' : ''; // 因为modal跳出fr的dom层级了,需要重新加个顶层的className
9+
} catch (error) {}
410
return (
5-
<div className="fr-map">
6-
{Object.keys(p.value).map(name =>
7-
p.getSubField({
11+
<div className={className}>
12+
{Object.keys(p.value).map(name => {
13+
return p.getSubField({
814
name,
915
value: p.value[name],
1016
onChange(key, val, objValue) {
@@ -33,8 +39,8 @@ export default function map(p) {
3339
p.onChange(p.name, value);
3440
},
3541
rootValue: p.value,
36-
})
37-
)}
42+
});
43+
})}
3844
</div>
3945
);
4046
}

src/widgets/antd/list.jsx

+65-6
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* 数组组件
44
*/
55

6-
import React from 'react';
6+
import React, { useState } from 'react';
77
import listHoc from '../../components/listHoc';
88
import * as Icons from '@ant-design/icons';
9-
10-
import { Button } from 'antd';
9+
import { isObj } from '../../base/utils';
10+
import { Button, Modal, Drawer } from 'antd';
1111

1212
function FrButton({ icon, children, ...rest }) {
1313
let iconName;
@@ -25,12 +25,71 @@ function FrButton({ icon, children, ...rest }) {
2525
const IconComponent = Icons[iconName];
2626
if (IconComponent) {
2727
return (
28-
<Button {...rest} icon={<IconComponent />}>
28+
<Button {...rest} size="small" icon={<IconComponent />}>
2929
{children}
3030
</Button>
3131
);
3232
}
33-
return <Button {...rest}>{children}</Button>;
33+
return (
34+
<Button {...rest} size="small">
35+
{children}
36+
</Button>
37+
);
3438
}
3539

36-
export default listHoc(FrButton);
40+
const List = listHoc(FrButton);
41+
42+
const ListWithModal = props => {
43+
const { options, schema } = props || {};
44+
const [show, setShow] = useState(false);
45+
const toggle = () => setShow(o => !o);
46+
if (options && options.modal) {
47+
const config = isObj(options.modal) ? options.modal : {};
48+
const { text } = config;
49+
return (
50+
<div>
51+
<a className="pointer" onClick={toggle}>
52+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
53+
</a>
54+
<Modal
55+
title={(schema && schema.title) || '子配置'}
56+
visible={show}
57+
onCancel={toggle}
58+
footer={null}
59+
width="80%"
60+
{...config}
61+
style={{ maxWidth: 800, ...config.style }}
62+
>
63+
<div className="fr-wrapper">
64+
<List {...props} />
65+
</div>
66+
</Modal>
67+
</div>
68+
);
69+
}
70+
if (options && options.drawer) {
71+
const config = isObj(options.drawer) ? options.drawer : {};
72+
const { text } = config;
73+
return (
74+
<div>
75+
<a className="pointer" onClick={toggle}>
76+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
77+
</a>
78+
<Drawer
79+
title={(schema && schema.title) || '子配置'}
80+
visible={show}
81+
onClose={toggle}
82+
width="80%"
83+
{...config}
84+
>
85+
<div className="fr-wrapper">
86+
<List {...props} />
87+
</div>
88+
</Drawer>
89+
</div>
90+
);
91+
}
92+
return <List {...props} />;
93+
};
94+
95+
export default ListWithModal;

src/widgets/antd/map.jsx

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,55 @@
1-
import map from '../../components/map';
2-
export default map;
1+
import React, { useState } from 'react';
2+
import { Modal, Drawer } from 'antd';
3+
import { isObj } from '../../base/utils';
4+
import Map from '../../components/map';
5+
6+
const MapWithModal = props => {
7+
const { options = {}, schema } = props || {};
8+
const [show, setShow] = useState(false);
9+
const toggle = () => setShow(o => !o);
10+
if (options && options.modal) {
11+
const config = isObj(options.modal) ? options.modal : {};
12+
const { text } = config;
13+
return (
14+
<div>
15+
<a className="pointer" onClick={toggle}>
16+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
17+
</a>
18+
<Modal
19+
title={(schema && schema.title) || '子配置'}
20+
visible={show}
21+
onCancel={toggle}
22+
footer={null}
23+
width="80%"
24+
{...config}
25+
style={{ maxWidth: 800, ...config.style }}
26+
>
27+
<Map {...props} />
28+
</Modal>
29+
</div>
30+
);
31+
}
32+
if (options && options.drawer) {
33+
const config = isObj(options.drawer) ? options.drawer : {};
34+
const { text } = config;
35+
return (
36+
<div>
37+
<a className="pointer" onClick={toggle}>
38+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
39+
</a>
40+
<Drawer
41+
title={(schema && schema.title) || '子配置'}
42+
visible={show}
43+
onClose={toggle}
44+
width="80%"
45+
{...config}
46+
>
47+
<Map {...props} />
48+
</Drawer>
49+
</div>
50+
);
51+
}
52+
return <Map {...props} />;
53+
};
54+
55+
export default MapWithModal;

src/widgets/fusion/list.jsx

+58-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import React from 'react';
2-
import { Button, Icon } from '@alifd/next';
1+
import React, { useState } from 'react';
2+
import { Button, Icon, Dialog as Modal, Drawer } from '@alifd/next';
33
import listHoc from '../../components/listHoc';
4+
import { isObj } from '../../base/utils';
45

56
function FrButton({ icon, children, type, ...rest }) {
67
let iconName;
@@ -23,4 +24,58 @@ function FrButton({ icon, children, type, ...rest }) {
2324
);
2425
}
2526

26-
export default listHoc(FrButton);
27+
const List = listHoc(FrButton);
28+
29+
const ListWithModal = props => {
30+
const { options, schema } = props || {};
31+
const [show, setShow] = useState(false);
32+
const toggle = () => setShow(o => !o);
33+
if (options && options.modal) {
34+
const config = isObj(options.modal) ? options.modal : {};
35+
const { text } = config;
36+
return (
37+
<div>
38+
<a className="pointer" onClick={toggle}>
39+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
40+
</a>
41+
<Modal
42+
title={(schema && schema.title) || '子配置'}
43+
visible={show}
44+
onClose={toggle}
45+
footer={false}
46+
{...config}
47+
style={{ maxWidth: 800, width: '80%', ...config.style }}
48+
>
49+
<div className="fr-wrapper">
50+
<List {...props} />
51+
</div>
52+
</Modal>
53+
</div>
54+
);
55+
}
56+
if (options && options.drawer) {
57+
const config = isObj(options.drawer) ? options.drawer : {};
58+
const { text } = config;
59+
return (
60+
<div>
61+
<a className="pointer" onClick={toggle}>
62+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
63+
</a>
64+
<Drawer
65+
title={(schema && schema.title) || '子配置'}
66+
visible={show}
67+
onClose={toggle}
68+
width="80%"
69+
{...config}
70+
>
71+
<div className="fr-wrapper">
72+
<List {...props} />
73+
</div>
74+
</Drawer>
75+
</div>
76+
);
77+
}
78+
return <List {...props} />;
79+
};
80+
81+
export default ListWithModal;

src/widgets/fusion/map.jsx

+54-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,54 @@
1-
import map from '../../components/map';
2-
export default map;
1+
import React, { useState } from 'react';
2+
import { Dialog as Modal, Drawer } from '@alifd/next';
3+
import { isObj } from '../../base/utils';
4+
import Map from '../../components/map';
5+
6+
const MapWithModal = props => {
7+
const { options = {}, schema } = props || {};
8+
const [show, setShow] = useState(false);
9+
const toggle = () => setShow(o => !o);
10+
if (options && options.modal) {
11+
const config = isObj(options.modal) ? options.modal : {};
12+
const { text } = config;
13+
return (
14+
<div>
15+
<a className="pointer" onClick={toggle}>
16+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
17+
</a>
18+
<Modal
19+
title={(schema && schema.title) || '子配置'}
20+
visible={show}
21+
onClose={toggle}
22+
footer={false}
23+
{...config}
24+
style={{ maxWidth: 800, width: '80%', ...config.style }}
25+
>
26+
<Map {...props} />
27+
</Modal>
28+
</div>
29+
);
30+
}
31+
if (options && options.drawer) {
32+
const config = isObj(options.drawer) ? options.drawer : {};
33+
const { text } = config;
34+
return (
35+
<div>
36+
<a className="pointer" onClick={toggle}>
37+
{text && typeof text === 'string' ? '+ ' + text : '+ 配置'}
38+
</a>
39+
<Drawer
40+
title={(schema && schema.title) || '子配置'}
41+
visible={show}
42+
onClose={toggle}
43+
width="80%"
44+
{...config}
45+
>
46+
<Map {...props} />
47+
</Drawer>
48+
</div>
49+
);
50+
}
51+
return <Map {...props} />;
52+
};
53+
54+
export default MapWithModal;

0 commit comments

Comments
 (0)