forked from p96170835/amis
替换掉react-bootstrap中的组件
This commit is contained in:
parent
e8ac509337
commit
f0967a699e
|
@ -11,7 +11,6 @@ const mapping: {
|
|||
'immutability-helper': __moduleId('react-addons-update'),
|
||||
'react-cropper': __moduleId('react-cropper'),
|
||||
'react-dropzone': __moduleId('react-dropzone'),
|
||||
'react-bootstrap': __moduleId('react-bootstrap'),
|
||||
'classnames': __moduleId('classnames'),
|
||||
'axios': __moduleId('axios'),
|
||||
'moment': __moduleId('moment'),
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
"rc-input-number": "4.4.5",
|
||||
"react": "^16.8.6",
|
||||
"react-addons-update": "15.6.2",
|
||||
"react-bootstrap": "^0.32.3",
|
||||
"react-overlays": "^0.8.3",
|
||||
"react-color": "2.13.8",
|
||||
"react-cropper": "1.0.0",
|
||||
|
@ -88,7 +87,6 @@
|
|||
"@types/qs": "^6.5.1",
|
||||
"@types/react": "^16.8.1",
|
||||
"@types/react-addons-update": "^0.14.19",
|
||||
"@types/react-bootstrap": "^0.32.3",
|
||||
"@types/react-color": "^2.13.3",
|
||||
"@types/react-cropper": "^0.10.1",
|
||||
"@types/react-dom": "^16.0.7",
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
.#{$ns}Tabs {
|
||||
&-links {
|
||||
border-bottom: $Tabs-borderWidth solid $Tabs-borderColor;
|
||||
padding-left: 0;
|
||||
margin-bottom: 0;
|
||||
list-style: none;
|
||||
&::before {
|
||||
display: table;
|
||||
content: " ";
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-link {
|
||||
margin-bottom: -$Tabs-borderWidth;
|
||||
|
@ -17,6 +24,7 @@
|
|||
padding: $gap-sm $gap-base;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover > a,
|
||||
|
@ -49,6 +57,13 @@
|
|||
border-style: solid;
|
||||
border-width: 0 $Tabs-borderWidth $Tabs-borderWidth;
|
||||
border-color: $Tabs-borderColor;
|
||||
|
||||
> .tab-pane {
|
||||
display: none;
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--line {
|
||||
|
|
|
@ -1,3 +1,113 @@
|
|||
import {Collapse} from 'react-bootstrap';
|
||||
/**
|
||||
* @file Collapse
|
||||
* @description
|
||||
* @author fex
|
||||
*/
|
||||
|
||||
export default Collapse;
|
||||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import css = require('dom-helpers/style');
|
||||
import {ClassNamesFn, themeable} from '../theme';
|
||||
import Transition, { EXITED, ENTERED, ENTERING, EXITING } from 'react-transition-group/Transition';
|
||||
import { autobind } from '../utils/helper';
|
||||
|
||||
const collapseStyles: {
|
||||
[propName: string]: string;
|
||||
} = {
|
||||
[EXITED]: 'collapse',
|
||||
[EXITING]: 'collapsing',
|
||||
[ENTERING]: 'collapsing',
|
||||
[ENTERED]: 'collapse show',
|
||||
};
|
||||
|
||||
export interface CollapseProps {
|
||||
show?: boolean,
|
||||
mountOnEnter?: boolean,
|
||||
unmountOnExit?: boolean,
|
||||
className?: string,
|
||||
classPrefix: string;
|
||||
classnames: ClassNamesFn;
|
||||
}
|
||||
|
||||
export class Collapse extends React.Component<CollapseProps, any> {
|
||||
static defaultProps: Pick<
|
||||
CollapseProps,
|
||||
'show' | 'mountOnEnter' | 'unmountOnExit'
|
||||
> = {
|
||||
show: false,
|
||||
mountOnEnter: false,
|
||||
unmountOnExit: false
|
||||
}
|
||||
|
||||
contentDom: any;
|
||||
contentRef = (ref: any) => (this.contentDom = ref);
|
||||
|
||||
@autobind
|
||||
handleEnter(elem: HTMLElement) {
|
||||
elem.style['height'] = null;
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleEntering(elem: HTMLElement) {
|
||||
elem.style['height'] = `${elem['scrollHeight']}px`;
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleEntered(elem: HTMLElement) {
|
||||
elem.style['height'] = null;
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleExit(elem: HTMLElement) {
|
||||
let offsetHeight = elem['offsetHeight'];
|
||||
const height = offsetHeight + parseInt(css(elem, 'marginTop'), 10) + parseInt(css(elem, 'marginBottom'), 10);
|
||||
elem.style['height'] = `${height}px`;
|
||||
|
||||
// trigger browser reflow
|
||||
elem.offsetHeight;
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleExiting(elem: HTMLElement) {
|
||||
elem.style['height'] = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
show,
|
||||
children,
|
||||
mountOnEnter,
|
||||
unmountOnExit
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Transition
|
||||
mountOnEnter={mountOnEnter}
|
||||
unmountOnExit={unmountOnExit}
|
||||
in={show}
|
||||
timeout={300}
|
||||
onEnter={this.handleEnter}
|
||||
onEntering={this.handleEntering}
|
||||
onEntered={this.handleEntered}
|
||||
onExit={this.handleExit}
|
||||
onExiting={this.handleExiting}
|
||||
>
|
||||
{(status:string, innerProps:any) => {
|
||||
if (status === ENTERING) {
|
||||
this.contentDom.offsetWidth;
|
||||
}
|
||||
return React.cloneElement(children as any, {
|
||||
...innerProps,
|
||||
ref: this.contentRef,
|
||||
className: cx(
|
||||
collapseStyles[status],
|
||||
innerProps.className
|
||||
)
|
||||
})}
|
||||
}
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default themeable(Collapse);
|
|
@ -1,3 +0,0 @@
|
|||
import {DropdownButton} from 'react-bootstrap';
|
||||
|
||||
export default DropdownButton;
|
|
@ -15,7 +15,6 @@ import ColorPicker from './ColorPicker';
|
|||
import DatePicker from './DatePicker';
|
||||
import DateRangePicker from './DateRangePicker';
|
||||
import Drawer from './Drawer';
|
||||
import DropdownButton from './DropdownButton';
|
||||
// import Editor from './Editor';
|
||||
import Html from './Html';
|
||||
import * as Icons from './icons';
|
||||
|
@ -52,7 +51,6 @@ export {
|
|||
DatePicker,
|
||||
DateRangePicker,
|
||||
Drawer,
|
||||
DropdownButton,
|
||||
// Editor,
|
||||
Html,
|
||||
Icons,
|
||||
|
|
|
@ -26,7 +26,6 @@ import {
|
|||
DatePicker,
|
||||
DateRangePicker,
|
||||
Drawer,
|
||||
DropdownButton,
|
||||
// Editor,
|
||||
Icons,
|
||||
Html,
|
||||
|
@ -192,7 +191,6 @@ export {
|
|||
DatePicker,
|
||||
DateRangePicker,
|
||||
Drawer,
|
||||
DropdownButton,
|
||||
// Editor,
|
||||
Html,
|
||||
Icons,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import {Renderer, RendererProps} from '../factory';
|
||||
import cx from 'classnames';
|
||||
import {Collapse as BasicCollapse} from 'react-bootstrap';
|
||||
import { Renderer, RendererProps } from '../factory';
|
||||
import { Collapse as BasicCollapse } from '../components/Collapse';
|
||||
|
||||
export interface CollapseProps extends RendererProps {
|
||||
title?: string; // 标题
|
||||
|
@ -81,8 +80,6 @@ export default class Collapse extends React.Component<CollapseProps, CollapseSta
|
|||
collapsable,
|
||||
} = this.props;
|
||||
|
||||
// todo 换掉 bootstrap 的 collapse
|
||||
|
||||
return (
|
||||
<WrapperComponent
|
||||
className={cx(
|
||||
|
@ -102,7 +99,7 @@ export default class Collapse extends React.Component<CollapseProps, CollapseSta
|
|||
</HeadingComponent>
|
||||
) : null}
|
||||
|
||||
<BasicCollapse in={collapsable ? !this.state.collapsed : true}>
|
||||
<BasicCollapse show={collapsable ? !this.state.collapsed : true} classnames={cx} classPrefix={ns}>
|
||||
<div className={cx(`Collapse-body`, bodyClassName)}>
|
||||
{children
|
||||
? typeof children === 'function'
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
} from './Item';
|
||||
import pick = require("lodash/pick");
|
||||
import React from 'react';
|
||||
import { Row, Col } from "react-bootstrap";
|
||||
import cx from 'classnames';
|
||||
|
||||
export interface GridProps extends FormControlProps {};
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import React from 'react';
|
||||
import {Renderer, RendererProps} from '../factory';
|
||||
import {ServiceStore, IServiceStore} from '../store/service';
|
||||
import {Api, SchemaNode, Schema, Action} from '../types';
|
||||
import {filter, evalExpression} from '../utils/tpl';
|
||||
import {Tabs as BsTabs, TabContainer, TabContent, TabPane, NavItem, Nav, Tab} from 'react-bootstrap';
|
||||
import cx = require('classnames');
|
||||
import { Schema } from '../types';
|
||||
import { evalExpression } from '../utils/tpl';
|
||||
import Transition, {ENTERED, ENTERING} from 'react-transition-group/Transition';
|
||||
import find = require('lodash/find');
|
||||
import {isVisible} from '../utils/helper';
|
||||
import { isVisible } from '../utils/helper';
|
||||
import findIndex = require('lodash/findIndex');
|
||||
|
||||
const transitionStyles: {
|
||||
[propName: string]: string;
|
||||
} = {
|
||||
[ENTERING]: 'in',
|
||||
[ENTERED]: 'in'
|
||||
};
|
||||
|
||||
export type TabProps = Schema & {
|
||||
title?: string; // 标题
|
||||
icon?: string;
|
||||
|
@ -30,9 +35,9 @@ export interface TabsState {
|
|||
prevKey: any;
|
||||
}
|
||||
|
||||
let tabCount = 0;
|
||||
|
||||
export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
wrapperRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
|
||||
static defaultProps: Partial<TabsProps> = {
|
||||
className: '',
|
||||
mode: '',
|
||||
|
@ -40,7 +45,6 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
|||
unmountOnExit: false,
|
||||
};
|
||||
|
||||
id = '' + tabCount++;
|
||||
constructor(props: TabsProps) {
|
||||
super(props);
|
||||
|
||||
|
@ -155,7 +159,7 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
|||
// 是 hash,需要更新到地址栏
|
||||
if (typeof key === 'string' && env) {
|
||||
env.updateLocation(`#${key}`);
|
||||
} else if (typeof this.state.prevKey === 'string' && env) {
|
||||
} else if (typeof this.state.activeKey === 'string' && env) {
|
||||
env.updateLocation(`#`);
|
||||
}
|
||||
|
||||
|
@ -207,8 +211,7 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
|||
const mode = tabsMode || dMode;
|
||||
|
||||
return (
|
||||
<TabContainer
|
||||
id={this.id}
|
||||
<div
|
||||
className={cx(
|
||||
`Tabs`,
|
||||
{
|
||||
|
@ -216,49 +219,63 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
|||
},
|
||||
className
|
||||
)}
|
||||
activeKey={this.state.activeKey}
|
||||
onSelect={this.handleSelect}
|
||||
>
|
||||
<div>
|
||||
<Nav className={cx('Tabs-links')} role="tablist">
|
||||
{tabs.map((tab, index) => isVisible(tab, data) ? (
|
||||
<NavItem
|
||||
className={cx('Tabs-link')}
|
||||
key={index}
|
||||
eventKey={tab.hash || index}
|
||||
disabled={tab.disabled || (tab.disabledOn && evalExpression(tab.disabledOn, data))}
|
||||
>
|
||||
{tab.icon ? (
|
||||
<div>
|
||||
<i className={tab.icon} /> {tab.title}
|
||||
</div>
|
||||
) : (
|
||||
tab.title
|
||||
)}
|
||||
</NavItem>
|
||||
) : null)}
|
||||
</Nav>
|
||||
<ul className={cx('Tabs-links')} role="tablist">
|
||||
{tabs.map((tab, index) => isVisible(tab, data) ? (
|
||||
<li
|
||||
className={cx(
|
||||
'Tabs-link',
|
||||
this.state.activeKey === tab.hash || this.state.activeKey === index ? 'active' : '',
|
||||
tab.disabled || (tab.disabledOn && evalExpression(tab.disabledOn, data)) ? 'disabled' : ''
|
||||
)}
|
||||
key={index}
|
||||
onClick={() => tab.disabled || (tab.disabledOn && evalExpression(tab.disabledOn, data)) ? '' : this.handleSelect(tab.hash || index)}
|
||||
>
|
||||
{tab.icon ? (
|
||||
<div>
|
||||
<i className={tab.icon} /><a>{tab.title}</a>
|
||||
</div>
|
||||
) : (
|
||||
<a>{tab.title}</a>
|
||||
)}
|
||||
</li>
|
||||
) : null)}
|
||||
</ul>
|
||||
|
||||
<TabContent
|
||||
className={cx('Tabs-content', contentClassName)}
|
||||
mountOnEnter={mountOnEnter}
|
||||
unmountOnExit={unmountOnExit}
|
||||
>
|
||||
{tabs.map((tab, index) => isVisible(tab, data) ? (
|
||||
<TabPane
|
||||
key={index}
|
||||
eventKey={tab.hash || index}
|
||||
mountOnEnter={mountOnEnter}
|
||||
unmountOnExit={typeof tab.reload === 'boolean' ? tab.reload : tab.unmountOnExit}
|
||||
>
|
||||
{tabRender
|
||||
? tabRender(tab, this.props)
|
||||
: render(`tab/${index}`, tab.tab || tab.body || '')}
|
||||
</TabPane>
|
||||
) : null)}
|
||||
</TabContent>
|
||||
<div
|
||||
ref={this.wrapperRef}
|
||||
className={cx('Tabs-content', contentClassName, 'tab-content')}
|
||||
>
|
||||
{tabs.map((tab, index) => isVisible(tab, data) ? (
|
||||
<Transition
|
||||
in={this.state.activeKey === tab.hash || this.state.activeKey === index ? true : false}
|
||||
mountOnEnter={mountOnEnter}
|
||||
unmountOnExit={unmountOnExit}
|
||||
timeout={500}
|
||||
key={index}
|
||||
>
|
||||
{(status:string) => {
|
||||
if (status === ENTERING) {
|
||||
this.wrapperRef.current && this.wrapperRef.current.childNodes.forEach((item:HTMLElement) => item.offsetHeight);
|
||||
}
|
||||
return (
|
||||
<div className={cx(
|
||||
transitionStyles[status],
|
||||
this.state.activeKey === tab.hash || this.state.activeKey === index ? 'active' : '',
|
||||
'tab-pane',
|
||||
'fade'
|
||||
)}>
|
||||
{tabRender
|
||||
? tabRender(tab, this.props)
|
||||
: render(`tab/${index}`, tab.tab || tab.body || '')}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</Transition>
|
||||
) : null)
|
||||
}
|
||||
</div>
|
||||
</TabContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue