@sheinoutmobile/shineoutmobile 1.8.2
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.
Potentially problematic release.
This version of @sheinoutmobile/shineoutmobile might be problematic. Click here for more details.
- package/.eslintignore +20 -0
- package/.eslintrc +8 -0
- package/.gitlab-ci.yml +53 -0
- package/.yarnrc +1 -0
- package/CHANGELOG.md +8 -0
- package/README.md +14 -0
- package/build.config.js +6 -0
- package/doc.config.js +16 -0
- package/lib/index.esm.js +5414 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/package.json +47 -0
- package/src/component/button/button.jsx +83 -0
- package/src/component/button/index.jsx +3 -0
- package/src/component/button/style.less +132 -0
- package/src/component/cell/cell.jsx +71 -0
- package/src/component/cell/index.jsx +3 -0
- package/src/component/cell/style.less +86 -0
- package/src/component/cell-group/cell-group.jsx +26 -0
- package/src/component/cell-group/index.jsx +3 -0
- package/src/component/cell-group/style.less +22 -0
- package/src/component/checkbox/checkbox.jsx +92 -0
- package/src/component/checkbox/index.js +3 -0
- package/src/component/checkbox/kind/checkbox-button.jsx +41 -0
- package/src/component/checkbox/style.less +49 -0
- package/src/component/dialog/dialog.jsx +58 -0
- package/src/component/dialog/index.js +3 -0
- package/src/component/dialog/kind/dialog-alert.jsx +22 -0
- package/src/component/dialog/kind/dialog-confirm.jsx +54 -0
- package/src/component/dialog/style.less +80 -0
- package/src/component/drawer/drawer.jsx +151 -0
- package/src/component/drawer/index.jsx +3 -0
- package/src/component/drawer/js/tools.js +1 -0
- package/src/component/drawer/style.less +17 -0
- package/src/component/field/field.jsx +49 -0
- package/src/component/field/index.js +3 -0
- package/src/component/icon/icon.jsx +55 -0
- package/src/component/icon/index.jsx +19 -0
- package/src/component/icon/style.less +9 -0
- package/src/component/icons/index.js +3 -0
- package/src/component/icons/mrp.js +3 -0
- package/src/component/image-previewer/image-previewer.jsx +54 -0
- package/src/component/image-previewer/index.js +3 -0
- package/src/component/index-sort-list/group.jsx +49 -0
- package/src/component/index-sort-list/index-bar.jsx +34 -0
- package/src/component/index-sort-list/index.js +3 -0
- package/src/component/index-sort-list/js/rules.js +14 -0
- package/src/component/index-sort-list/js/sort-rule.js +41 -0
- package/src/component/index-sort-list/list.jsx +110 -0
- package/src/component/index-sort-list/style.less +109 -0
- package/src/component/input/index.js +3 -0
- package/src/component/input/input.jsx +285 -0
- package/src/component/input/style.less +77 -0
- package/src/component/list-view/index.js +3 -0
- package/src/component/list-view/jsx/empty.jsx +23 -0
- package/src/component/list-view/list-view.jsx +165 -0
- package/src/component/list-view/style.less +79 -0
- package/src/component/loading/index.js +3 -0
- package/src/component/loading/loading.jsx +97 -0
- package/src/component/loading/styles.less +128 -0
- package/src/component/multiple-selector/index.jsx +3 -0
- package/src/component/multiple-selector/item.jsx +23 -0
- package/src/component/multiple-selector/multiple-selector.jsx +116 -0
- package/src/component/multiple-selector/selector.jsx +41 -0
- package/src/component/multiple-selector/style.less +78 -0
- package/src/component/notice-bar/index.jsx +3 -0
- package/src/component/notice-bar/notice-bar.jsx +86 -0
- package/src/component/notice-bar/style.less +72 -0
- package/src/component/notify/index.js +37 -0
- package/src/component/notify/notify.jsx +125 -0
- package/src/component/notify/style.less +48 -0
- package/src/component/picker/drawPicker.jsx +110 -0
- package/src/component/picker/index.js +3 -0
- package/src/component/picker/picker.jsx +380 -0
- package/src/component/picker/pickerItem.jsx +31 -0
- package/src/component/picker/style.less +80 -0
- package/src/component/pull-refresh/index.js +3 -0
- package/src/component/pull-refresh/pull-refresh.jsx +46 -0
- package/src/component/search-bar/index.jsx +3 -0
- package/src/component/search-bar/search-bar.jsx +97 -0
- package/src/component/search-bar/style.less +52 -0
- package/src/component/sign/index.jsx +3 -0
- package/src/component/sign/sign.jsx +33 -0
- package/src/component/sign/style.less +56 -0
- package/src/component/sort-item/index.jsx +3 -0
- package/src/component/sort-item/sort-item.jsx +52 -0
- package/src/component/sort-item/style.less +52 -0
- package/src/component/subscript/index.js +3 -0
- package/src/component/subscript/style.less +63 -0
- package/src/component/subscript/subscript.jsx +77 -0
- package/src/component/tab/index.jsx +6 -0
- package/src/component/tab/nav-child.jsx +63 -0
- package/src/component/tab/panel.jsx +22 -0
- package/src/component/tab/style.less +87 -0
- package/src/component/tab/tab.jsx +195 -0
- package/src/component/tag/index.jsx +3 -0
- package/src/component/tag/style.less +56 -0
- package/src/component/tag/tag.jsx +52 -0
- package/src/component/toast/content.jsx +31 -0
- package/src/component/toast/index.js +3 -0
- package/src/component/toast/style.less +50 -0
- package/src/component/toast/toast.jsx +62 -0
- package/src/component/touchable/index.js +3 -0
- package/src/component/touchable/style.less +33 -0
- package/src/component/touchable/touchable.jsx +43 -0
- package/src/component/uploader/index.jsx +445 -0
- package/src/component/uploader/js/get-image-base64.js +31 -0
- package/src/component/uploader/js/get-image-detail.js +26 -0
- package/src/component/uploader/js/index.js +77 -0
- package/src/component/uploader/js/merge-class-name.js +14 -0
- package/src/component/uploader/js/old-compress-function.js +64 -0
- package/src/component/uploader/js/request.js +62 -0
- package/src/component/uploader/js/tools.js +115 -0
- package/src/component/uploader/jsx/config.jsx +36 -0
- package/src/component/uploader/jsx/img-preview.jsx +41 -0
- package/src/component/uploader/jsx/thumbnails.jsx +27 -0
- package/src/component/uploader/styles/index.less +158 -0
- package/src/index.js +1 -0
- package/src/index.jsx +64 -0
- package/src/styles/color.less +51 -0
- package/src/styles/font.less +14 -0
- package/src/styles/format-theme.less +27 -0
- package/src/styles/index.less +26 -0
- package/src/styles/spacing.less +3 -0
- package/src/styles/var.less +3 -0
- package/src/tools/create-body-container.js +47 -0
- package/src/tools/limit-body-scroll.js +17 -0
- package/src/tools/limit-document-scroll.js +12 -0
- package/src/tools/merge-class-name.js +14 -0
- package/src/tools/object-key-check.js +3 -0
- package/src/tools/pinyin.js +6 -0
- package/src/tools/proptypes.js +51 -0
- package/src/tools/style.less +14 -0
- package/test/cases/case-button01.assert.js +6 -0
- package/test/cases/case-button01.source.jsx +28 -0
- package/test/cases/case-checkbox01.assert.js +6 -0
- package/test/cases/case-checkbox01.source.jsx +20 -0
- package/test/cases/case-dialog01.assert.js +6 -0
- package/test/cases/case-dialog01.source.jsx +45 -0
- package/test/cases/case-drawer01.assert.js +6 -0
- package/test/cases/case-drawer01.source.jsx +85 -0
- package/test/cases/case-icons01.assert.js +6 -0
- package/test/cases/case-icons01.source.jsx +25 -0
- package/test/cases/case-indexSortList01.assert.js +6 -0
- package/test/cases/case-indexSortList01.source.jsx +74 -0
- package/test/cases/case-input01.assert.js +6 -0
- package/test/cases/case-input01.source.jsx +24 -0
- package/test/cases/case-listView01.assert.js +6 -0
- package/test/cases/case-listView01.source.jsx +64 -0
- package/test/cases/case-multiplePicker01.assert.js +6 -0
- package/test/cases/case-multiplePicker01.source.jsx +60 -0
- package/test/cases/case-multipleSelector01.assert.js +6 -0
- package/test/cases/case-multipleSelector01.source.jsx +49 -0
- package/test/cases/case-noticebar01.assert.js +6 -0
- package/test/cases/case-noticebar01.source.jsx +21 -0
- package/test/cases/case-picker01.assert.js +6 -0
- package/test/cases/case-picker01.source.jsx +61 -0
- package/test/cases/case-refresh01.assert.js +6 -0
- package/test/cases/case-refresh01.source.jsx +33 -0
- package/test/cases/case-sign01.assert.js +6 -0
- package/test/cases/case-sign01.source.jsx +21 -0
- package/test/cases/case-subscript01.assert.js +6 -0
- package/test/cases/case-subscript01.source.jsx +30 -0
- package/test/cases/case-tab01.assert.js +6 -0
- package/test/cases/case-tab01.source.jsx +51 -0
- package/test/cases/case-toast01.assert.js +6 -0
- package/test/cases/case-toast01.source.jsx +32 -0
- package/test/cases/case-uploader01.assert.js +6 -0
- package/test/cases/case-uploader01.source.jsx +45 -0
- package/test.config.js +25 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, unmountComponentAtNode } from 'react-dom';
|
|
3
|
+
import Container from '../../tools/create-body-container';
|
|
4
|
+
import { prohibited, restore } from '../../tools/limit-document-scroll';
|
|
5
|
+
|
|
6
|
+
import Alert from './kind/dialog-alert';
|
|
7
|
+
import Confirm from './kind/dialog-confirm';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const container = new Container('dialog', { background: true });
|
|
11
|
+
|
|
12
|
+
const unMount = () => {
|
|
13
|
+
unmountComponentAtNode(container.getEl());
|
|
14
|
+
container.hidden();
|
|
15
|
+
restore();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Dialog = {
|
|
19
|
+
alert(content) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
render(
|
|
22
|
+
<Alert
|
|
23
|
+
{...content}
|
|
24
|
+
onOk={() => {
|
|
25
|
+
unMount();
|
|
26
|
+
resolve();
|
|
27
|
+
}}
|
|
28
|
+
/>,
|
|
29
|
+
container.getEl(),
|
|
30
|
+
);
|
|
31
|
+
container.visible();
|
|
32
|
+
prohibited();
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
confirm(content) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
render(
|
|
39
|
+
<Confirm
|
|
40
|
+
{...content}
|
|
41
|
+
onOk={() => {
|
|
42
|
+
unMount();
|
|
43
|
+
resolve();
|
|
44
|
+
}}
|
|
45
|
+
onCancel={() => {
|
|
46
|
+
unMount();
|
|
47
|
+
reject();
|
|
48
|
+
}}
|
|
49
|
+
/>,
|
|
50
|
+
container.getEl(),
|
|
51
|
+
);
|
|
52
|
+
container.visible();
|
|
53
|
+
prohibited();
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default Dialog;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from '../style.less';
|
|
4
|
+
|
|
5
|
+
const DialogAlert = ({ title, message, onOk, onCancel }) => (
|
|
6
|
+
<div className={styles.cover} onClick={onCancel || onOk}>
|
|
7
|
+
<div className={styles.dialog} onClick={e => e.stopPropagation()}>
|
|
8
|
+
<header>{title}</header>
|
|
9
|
+
<article>{message}</article>
|
|
10
|
+
<footer className={styles['dialog-alert-footer']} onClick={onOk}>确认</footer>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
DialogAlert.propTypes = {
|
|
16
|
+
title: PropTypes.node,
|
|
17
|
+
message: PropTypes.node,
|
|
18
|
+
onOk: PropTypes.func,
|
|
19
|
+
onCancel: PropTypes.func,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default DialogAlert;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import mergeClassName from '../../../tools/merge-class-name';
|
|
4
|
+
import styles from '../style.less';
|
|
5
|
+
|
|
6
|
+
const name = 'dialog-confirm';
|
|
7
|
+
|
|
8
|
+
const DialogConfirm = ({ title, message, onOk, onCancel, confirmButtonText, cancelButtonText }) => (
|
|
9
|
+
<div className={styles.cover} onClick={onCancel || onOk}>
|
|
10
|
+
<div className={styles.dialog} onClick={e => e.stopPropagation()}>
|
|
11
|
+
<header
|
|
12
|
+
style={!message ? {
|
|
13
|
+
flex: 1,
|
|
14
|
+
display: 'flex',
|
|
15
|
+
justifyContent: 'center',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
} : {}}
|
|
18
|
+
>
|
|
19
|
+
{title}
|
|
20
|
+
</header>
|
|
21
|
+
{message && <article>{message}</article>}
|
|
22
|
+
<footer className={styles[`${name}-footer`]}>
|
|
23
|
+
<span
|
|
24
|
+
className={mergeClassName([styles[`${name}-footer-button`], styles[`${name}-footer-cancel-button`]])}
|
|
25
|
+
onClick={onCancel}
|
|
26
|
+
>
|
|
27
|
+
{cancelButtonText}
|
|
28
|
+
</span>
|
|
29
|
+
<span
|
|
30
|
+
className={mergeClassName([styles[`${name}-footer-button`], styles[`${name}-footer-success-button`]])}
|
|
31
|
+
onClick={onOk}
|
|
32
|
+
>
|
|
33
|
+
{confirmButtonText}
|
|
34
|
+
</span>
|
|
35
|
+
</footer>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
DialogConfirm.propTypes = {
|
|
41
|
+
title: PropTypes.node,
|
|
42
|
+
message: PropTypes.node,
|
|
43
|
+
onOk: PropTypes.func,
|
|
44
|
+
onCancel: PropTypes.func,
|
|
45
|
+
confirmButtonText: PropTypes.node,
|
|
46
|
+
cancelButtonText: PropTypes.node,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
DialogConfirm.defaultProps = {
|
|
50
|
+
confirmButtonText: '确认',
|
|
51
|
+
cancelButtonText: '取消',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default DialogConfirm;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@import "../../styles/color";
|
|
2
|
+
@import "../../styles/font";
|
|
3
|
+
|
|
4
|
+
.cover{
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.dialog{
|
|
10
|
+
width: 280px;
|
|
11
|
+
max-width: 90%;
|
|
12
|
+
min-height: 160px;
|
|
13
|
+
max-height: 40%;
|
|
14
|
+
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: 50%;
|
|
20
|
+
left: 50%;
|
|
21
|
+
transform: translateX(-50%) translateY(-50%);
|
|
22
|
+
|
|
23
|
+
border-radius: 8px;
|
|
24
|
+
background: @white;
|
|
25
|
+
|
|
26
|
+
header{
|
|
27
|
+
padding: 23px 0;
|
|
28
|
+
text-align: center;
|
|
29
|
+
|
|
30
|
+
font-family: @medium;
|
|
31
|
+
font-size: @size-max;
|
|
32
|
+
font-weight: @weight-bold;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
article{
|
|
36
|
+
flex: 1;
|
|
37
|
+
padding: 0 10px 25px;
|
|
38
|
+
|
|
39
|
+
color: @gray-darker;
|
|
40
|
+
text-align: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&-alert-footer{
|
|
44
|
+
height: 50px;
|
|
45
|
+
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
align-items: center;
|
|
49
|
+
|
|
50
|
+
border-top: 1px solid @border-color;
|
|
51
|
+
|
|
52
|
+
color: @blue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&-confirm-footer{
|
|
56
|
+
height: 50px;
|
|
57
|
+
|
|
58
|
+
display: flex;
|
|
59
|
+
justify-content: space-between;
|
|
60
|
+
|
|
61
|
+
border-top: 1px solid @border-color;
|
|
62
|
+
|
|
63
|
+
&-cancel-button{
|
|
64
|
+
border-right: 1px solid @border-color;
|
|
65
|
+
color: @text-color;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&-success-button{
|
|
69
|
+
color: @blue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&-button{
|
|
73
|
+
display: flex;
|
|
74
|
+
width: 50%;
|
|
75
|
+
|
|
76
|
+
justify-content: center;
|
|
77
|
+
align-items: center;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDom from 'react-dom';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import styles from './style.less';
|
|
5
|
+
|
|
6
|
+
import Container from '../../tools/create-body-container';
|
|
7
|
+
import mergeClassName from '../../tools/merge-class-name';
|
|
8
|
+
import { getWidthHeight } from './js/tools';
|
|
9
|
+
import { prohibited, restore } from '../../tools/limit-document-scroll';
|
|
10
|
+
|
|
11
|
+
let i = 0;
|
|
12
|
+
|
|
13
|
+
class Drawer extends React.PureComponent {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
this.container = new Container(`drawer${i++}`);
|
|
17
|
+
this.containerEl = this.container.getEl();
|
|
18
|
+
|
|
19
|
+
this.drawer = React.createRef();
|
|
20
|
+
this.startY = 0;
|
|
21
|
+
|
|
22
|
+
this.onTouchStart = this.onTouchStart.bind(this);
|
|
23
|
+
this.onTouchEnd = this.onTouchEnd.bind(this);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 双重保障1,这里监听touchmove事件,目的是触底or触顶时,阻止滚动穿透
|
|
27
|
+
// componentDidMount() {
|
|
28
|
+
// this.drawer.current.addEventListener(
|
|
29
|
+
// 'touchmove',
|
|
30
|
+
// (e) => {
|
|
31
|
+
// const { current } = this.drawer;
|
|
32
|
+
// if (
|
|
33
|
+
// (current.scrollTop <= 0 && e.touches[0].pageY > this.startY)
|
|
34
|
+
// || (current.clientHeight + current.scrollTop >= current.scrollHeight
|
|
35
|
+
// && e.touches[0].pageY < this.startY)
|
|
36
|
+
// ) {
|
|
37
|
+
// return e.cancelable && e.preventDefault();
|
|
38
|
+
// }
|
|
39
|
+
// return true;
|
|
40
|
+
// },
|
|
41
|
+
// { passive: false },
|
|
42
|
+
// );
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
// componentWillReceiveProps(nextProps) {
|
|
46
|
+
// const { zIndex } = this.containerEl.style;
|
|
47
|
+
// console.log(this.containerEl.style.zIndex)
|
|
48
|
+
// if (zIndex !== nextProps.zIndex) {
|
|
49
|
+
// this.containerEl.style.zIndex = nextProps.zIndex;
|
|
50
|
+
// }
|
|
51
|
+
// }
|
|
52
|
+
|
|
53
|
+
componentWillUnmount() {
|
|
54
|
+
if (this.container) {
|
|
55
|
+
this.container.destroy();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 双重保障2,onTouchStart时,立即禁止页面body的滚动
|
|
60
|
+
onTouchStart(e) {
|
|
61
|
+
this.startY = e.touches[0].pageY;
|
|
62
|
+
prohibited();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
onTouchEnd() {
|
|
66
|
+
this.startY = 0;
|
|
67
|
+
restore();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setContainerVisible() {
|
|
71
|
+
const { visible } = this.props;
|
|
72
|
+
// 使用visibility的原因是display:none会影响过渡效果
|
|
73
|
+
if (visible) {
|
|
74
|
+
this.container.visible();
|
|
75
|
+
} else {
|
|
76
|
+
this.container.hidden();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getEl() {
|
|
81
|
+
const {
|
|
82
|
+
visible, position,
|
|
83
|
+
onClose, children,
|
|
84
|
+
drawerClass,
|
|
85
|
+
width,
|
|
86
|
+
height,
|
|
87
|
+
zIndex,
|
|
88
|
+
} = this.props;
|
|
89
|
+
|
|
90
|
+
this.setContainerVisible();
|
|
91
|
+
|
|
92
|
+
const style = { zIndex };
|
|
93
|
+
if (['left', 'right'].indexOf(position) >= 0) {
|
|
94
|
+
const realWidth = getWidthHeight(width);
|
|
95
|
+
style.width = realWidth;
|
|
96
|
+
style[position] = visible ? 0 : `calc(-${realWidth} - 5px)`; // 多移动5px是为了把boxshadow也藏起来
|
|
97
|
+
}
|
|
98
|
+
if (['top', 'bottom'].indexOf(position) >= 0) {
|
|
99
|
+
style.width = '100%';
|
|
100
|
+
const realHeight = getWidthHeight(height);
|
|
101
|
+
style.height = realHeight;
|
|
102
|
+
style[position] = visible ? 0 : `calc(-${realHeight} - 5px)`; // 多移动5px是为了把boxshadow也藏起来
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<div
|
|
107
|
+
className={styles.cover}
|
|
108
|
+
style={{ zIndex }}
|
|
109
|
+
onClick={onClose}
|
|
110
|
+
onTouchStart={this.onTouchStart}
|
|
111
|
+
onTouchEnd={this.onTouchEnd}
|
|
112
|
+
>
|
|
113
|
+
<div
|
|
114
|
+
ref={this.drawer}
|
|
115
|
+
style={style}
|
|
116
|
+
className={mergeClassName([styles.drawer, drawerClass])}
|
|
117
|
+
onClick={e => e.stopPropagation()}
|
|
118
|
+
>
|
|
119
|
+
{children}
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
render() {
|
|
126
|
+
const { zIndex } = this.props;
|
|
127
|
+
if (zIndex) this.containerEl.style.zIndex = zIndex;
|
|
128
|
+
|
|
129
|
+
return ReactDom.createPortal(this.getEl(), this.containerEl);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Drawer.propTypes = {
|
|
134
|
+
visible: PropTypes.bool,
|
|
135
|
+
position: PropTypes.oneOf(['top', 'bottom', 'right', 'left']),
|
|
136
|
+
onClose: PropTypes.func,
|
|
137
|
+
children: PropTypes.node,
|
|
138
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
139
|
+
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
140
|
+
drawerClass: PropTypes.string,
|
|
141
|
+
zIndex: PropTypes.number,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
Drawer.defaultProps = {
|
|
145
|
+
position: 'bottom',
|
|
146
|
+
width: 300,
|
|
147
|
+
height: 300,
|
|
148
|
+
zIndex: '',
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default Drawer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const getWidthHeight = wh => ((typeof wh === 'number') ? `${wh}px` : wh);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@import "../../styles/color";
|
|
2
|
+
|
|
3
|
+
.cover{
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100%;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
.drawer{
|
|
9
|
+
height: 100%;
|
|
10
|
+
background: @white;
|
|
11
|
+
position: absolute;
|
|
12
|
+
transition: all 0.25s;
|
|
13
|
+
box-shadow: 0 0 8px @text-color;
|
|
14
|
+
opacity: 2.5;
|
|
15
|
+
overflow: auto;
|
|
16
|
+
-webkit-overflow-scrolling: touch;
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Cell from "../cell";
|
|
4
|
+
import Input from "../input";
|
|
5
|
+
import { pick } from 'lodash-es';
|
|
6
|
+
|
|
7
|
+
class Field extends Component {
|
|
8
|
+
render() {
|
|
9
|
+
const cellProps = pick(this.props, Object.keys(Cell.propTypes).concat(['value']));
|
|
10
|
+
const inputProps = pick(this.props, Object.keys(Input.propTypes));
|
|
11
|
+
return (
|
|
12
|
+
<Cell
|
|
13
|
+
{...cellProps}
|
|
14
|
+
value={<Input {...inputProps} style={{ flex: 1 }}/>}
|
|
15
|
+
/>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Field.propTypes = {
|
|
21
|
+
...Cell.propTypes,
|
|
22
|
+
style: PropTypes.object,
|
|
23
|
+
className: PropTypes.string,
|
|
24
|
+
type: PropTypes.oneOf(['text', 'number', 'password', 'textarea', 'tel']),
|
|
25
|
+
defaultValue: PropTypes.string,
|
|
26
|
+
value: PropTypes.string,
|
|
27
|
+
align: PropTypes.oneOf(['left', 'center', 'right']),
|
|
28
|
+
readonly: PropTypes.bool,
|
|
29
|
+
disabled: PropTypes.bool,
|
|
30
|
+
border: PropTypes.bool,
|
|
31
|
+
placeholder: PropTypes.string,
|
|
32
|
+
clearable: PropTypes.bool,
|
|
33
|
+
maxLength: PropTypes.number,
|
|
34
|
+
autoSize: PropTypes.oneOfType([
|
|
35
|
+
PropTypes.bool,
|
|
36
|
+
PropTypes.shape({ width: PropTypes.number, height: PropTypes.number })
|
|
37
|
+
]),
|
|
38
|
+
showWordLimit: PropTypes.bool,
|
|
39
|
+
digits: PropTypes.number,
|
|
40
|
+
rows: PropTypes.number,
|
|
41
|
+
onChange: PropTypes.func,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
Field.defaultProps = {
|
|
45
|
+
...Cell.defaultProps,
|
|
46
|
+
...Input.defaultProps,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default Field;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import mergeClassName from '../../tools/merge-class-name';
|
|
4
|
+
import { getProps, defaultProps } from '../../tools/proptypes';
|
|
5
|
+
import iconClass from './style.less';
|
|
6
|
+
|
|
7
|
+
function Icon(props) {
|
|
8
|
+
const {
|
|
9
|
+
children,
|
|
10
|
+
className,
|
|
11
|
+
prefix,
|
|
12
|
+
style,
|
|
13
|
+
name,
|
|
14
|
+
fontFamily,
|
|
15
|
+
fontSize,
|
|
16
|
+
...otherProps
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const classNames = mergeClassName([iconClass['sm-icon'], className, `${prefix}-${name}`]);
|
|
20
|
+
|
|
21
|
+
const styles = Object.assign({}, {
|
|
22
|
+
fontFamily,
|
|
23
|
+
fontSize,
|
|
24
|
+
}, style);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<i {...otherProps} className={classNames} style={styles}>
|
|
28
|
+
{children}
|
|
29
|
+
</i>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Icon.propTypes = {
|
|
34
|
+
...getProps(PropTypes, 'children', 'className', 'size'),
|
|
35
|
+
type: PropTypes.string,
|
|
36
|
+
prefix: PropTypes.string,
|
|
37
|
+
name: PropTypes.string,
|
|
38
|
+
fontFamily: PropTypes.string,
|
|
39
|
+
fontSize: PropTypes.oneOfType([
|
|
40
|
+
PropTypes.string,
|
|
41
|
+
PropTypes.number,
|
|
42
|
+
]),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
Icon.defaultProps = {
|
|
46
|
+
...defaultProps,
|
|
47
|
+
prefix: 'icon',
|
|
48
|
+
fontFamily: 'iconfont',
|
|
49
|
+
name: '',
|
|
50
|
+
type: 'default',
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Icon.displayName = 'ShineoutMobileIcon';
|
|
54
|
+
|
|
55
|
+
export default Icon;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Icon from './icon';
|
|
3
|
+
|
|
4
|
+
const links = {};
|
|
5
|
+
|
|
6
|
+
export default function (url, fontFamily = 'iconfont', prefix = 'icon') {
|
|
7
|
+
if (url && !links[url]) {
|
|
8
|
+
links[url] = true;
|
|
9
|
+
const link = document.createElement('link');
|
|
10
|
+
link.setAttribute('rel', 'stylesheet');
|
|
11
|
+
link.setAttribute('type', 'text/css');
|
|
12
|
+
link.setAttribute('href', url);
|
|
13
|
+
document.head.appendChild(link);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const wrapperIcon = props => <Icon fontFamily={fontFamily} prefix={prefix} {...props} />;
|
|
17
|
+
wrapperIcon.isShineoutIcon = true;
|
|
18
|
+
return wrapperIcon;
|
|
19
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PhotoSlider } from 'react-photo-view';
|
|
3
|
+
import 'react-photo-view/dist/index.css';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
|
|
6
|
+
class ImagePreviewer extends React.PureComponent {
|
|
7
|
+
state = {
|
|
8
|
+
visible: false,
|
|
9
|
+
index: 0,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
render() {
|
|
13
|
+
const { src, images, children, renderThumb } = this.props;
|
|
14
|
+
const { visible, index } = this.state;
|
|
15
|
+
return (
|
|
16
|
+
<React.Fragment>
|
|
17
|
+
{children ? React.cloneElement(children, {
|
|
18
|
+
onClick: () => {
|
|
19
|
+
this.setState({ visible: true });
|
|
20
|
+
// eslint-disable-next-line react/prop-types
|
|
21
|
+
if (children && children.props.onClick) {
|
|
22
|
+
// eslint-disable-next-line react/prop-types
|
|
23
|
+
children.props.onClick();
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
}) : renderThumb()}
|
|
27
|
+
<PhotoSlider
|
|
28
|
+
images={(images || [src]).map(item => ({ src: item }))}
|
|
29
|
+
visible={visible}
|
|
30
|
+
onClose={() => this.setState({
|
|
31
|
+
visible: false,
|
|
32
|
+
})}
|
|
33
|
+
index={index}
|
|
34
|
+
onIndexChange={idx => this.setState({
|
|
35
|
+
index: idx,
|
|
36
|
+
})}
|
|
37
|
+
/>
|
|
38
|
+
</React.Fragment>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ImagePreviewer.propTypes = {
|
|
44
|
+
src: PropTypes.string,
|
|
45
|
+
images: PropTypes.arrayOf(PropTypes.string),
|
|
46
|
+
renderThumb: PropTypes.func,
|
|
47
|
+
children: PropTypes.node,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
ImagePreviewer.defaultProps = {
|
|
51
|
+
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default ImagePreviewer;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from './style.less';
|
|
4
|
+
import { getProps } from '../../tools/proptypes';
|
|
5
|
+
import mergeClassName from '../../tools/merge-class-name';
|
|
6
|
+
|
|
7
|
+
const name = 'sm-index-list-group';
|
|
8
|
+
|
|
9
|
+
class Group extends React.PureComponent {
|
|
10
|
+
render() {
|
|
11
|
+
const { index, title, data, render, click, forwardRef } = this.props;
|
|
12
|
+
const fixTopFlag = (title === index);
|
|
13
|
+
return (
|
|
14
|
+
<div ref={forwardRef} className={styles[name]}>
|
|
15
|
+
<p
|
|
16
|
+
className={mergeClassName([styles[`${name}-title`], fixTopFlag ? styles[`${name}-fix`] : null])}
|
|
17
|
+
>
|
|
18
|
+
{title}
|
|
19
|
+
</p>
|
|
20
|
+
<ul className={styles[`${name}-content`]} style={fixTopFlag ? { paddingTop: 32 } : {}}>
|
|
21
|
+
{
|
|
22
|
+
data.map(d => (
|
|
23
|
+
<li
|
|
24
|
+
className={styles[`${name}-content-cell`]}
|
|
25
|
+
onClick={() => click(d.value, d.label)}
|
|
26
|
+
>
|
|
27
|
+
{
|
|
28
|
+
typeof render === 'function'
|
|
29
|
+
? (<span className={styles[`${name}-content-cell-render`]}>{render(d)}</span>)
|
|
30
|
+
: (<text className={styles[`${name}-content-cell-text`]}>{d.label}</text>)
|
|
31
|
+
}
|
|
32
|
+
</li>
|
|
33
|
+
))
|
|
34
|
+
}
|
|
35
|
+
</ul>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Group.propTypes = {
|
|
42
|
+
...getProps(PropTypes, 'click', 'className'),
|
|
43
|
+
title: PropTypes.string,
|
|
44
|
+
data: PropTypes.arrayOf(PropTypes.object),
|
|
45
|
+
render: PropTypes.func,
|
|
46
|
+
forwardRef: PropTypes.func,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default React.forwardRef((props, ref) => <Group {...props} forwardRef={ref} />);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { getProps } from '../../tools/proptypes';
|
|
4
|
+
import styles from './style.less';
|
|
5
|
+
|
|
6
|
+
const name = 'sm-index-list-bar';
|
|
7
|
+
|
|
8
|
+
class IndexBar extends React.PureComponent {
|
|
9
|
+
render() {
|
|
10
|
+
const { index, indexList, click } = this.props;
|
|
11
|
+
return (
|
|
12
|
+
<ul className={styles[name]}>
|
|
13
|
+
{
|
|
14
|
+
indexList.map(i => (
|
|
15
|
+
<li
|
|
16
|
+
onClick={() => click(i)}
|
|
17
|
+
className={index === i && styles[`${name}-active`]}
|
|
18
|
+
>
|
|
19
|
+
{i[0]}
|
|
20
|
+
</li>
|
|
21
|
+
))
|
|
22
|
+
}
|
|
23
|
+
</ul>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
IndexBar.propTypes = {
|
|
29
|
+
...getProps(PropTypes, 'click'),
|
|
30
|
+
index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
31
|
+
indexList: PropTypes.arrayOf(PropTypes.string),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default IndexBar;
|