Merge branch 'master' into antd-3.0

This commit is contained in:
afc163 2017-08-17 18:03:28 +08:00
commit b84b17d981
33 changed files with 233 additions and 208 deletions

View File

@ -73,6 +73,18 @@ export default class Affix extends React.Component<AffixProps, any> {
fixedNode: HTMLElement;
};
events = [
'resize',
'scroll',
'touchstart',
'touchmove',
'touchend',
'pageshow',
'load',
];
eventHandlers = {};
constructor(props) {
super(props);
this.state = {
@ -190,7 +202,7 @@ export default class Affix extends React.Component<AffixProps, any> {
componentWillReceiveProps(nextProps) {
if (this.props.target !== nextProps.target) {
this.clearScrollEventListeners();
this.clearEventListeners();
this.setTargetEventListeners(nextProps.target);
// Mock Event object.
@ -199,7 +211,7 @@ export default class Affix extends React.Component<AffixProps, any> {
}
componentWillUnmount() {
this.clearScrollEventListeners();
this.clearEventListeners();
clearTimeout(this.timeout);
(this.updatePosition as any).cancel();
}
@ -209,15 +221,18 @@ export default class Affix extends React.Component<AffixProps, any> {
if (!target) {
return;
}
this.clearScrollEventListeners();
this.scrollEvent = addEventListener(target, 'scroll', this.updatePosition);
this.resizeEvent = addEventListener(target, 'resize', this.updatePosition);
this.clearEventListeners();
this.events.forEach(eventName => {
this.eventHandlers[eventName] = addEventListener(target, eventName, this.updatePosition);
});
}
clearScrollEventListeners() {
['scrollEvent', 'resizeEvent'].forEach((name) => {
if (this[name]) {
this[name].remove();
clearEventListeners() {
this.events.forEach(eventName => {
const handler = this.eventHandlers[eventName];
if (handler && handler.remove) {
handler.remove();
}
});
}

View File

@ -10,10 +10,17 @@ export default class InputElement extends React.Component<any, any> {
blur = () => {
this.ele.blur ? this.ele.blur() : (findDOMNode(this.ele) as HTMLInputElement).blur();
}
saveRef = (ele: HTMLInputElement) => {
this.ele = ele;
const childRef = this.props.children.ref;
if (typeof childRef === 'function') {
childRef(ele);
}
}
render() {
return React.cloneElement(this.props.children, {
...this.props,
ref: ele => this.ele = (ele as HTMLInputElement),
ref: this.saveRef,
}, null);
}
}

View File

@ -17,4 +17,14 @@ describe('AutoComplete with Custom Input Element Render', () => {
// should not filter data source defaultly
expect(dropdownWrapper.find('MenuItem').length).toBe(3);
});
it('child.ref should work', () => {
const mockRef = jest.fn();
mount(
<AutoComplete dataSource={[]}>
<input ref={mockRef} />
</AutoComplete>
);
expect(mockRef).toHaveBeenCalled();
});
});

View File

@ -15,6 +15,13 @@
.btn;
.btn-default;
// Make sure that the target of Button's click event always be `button`
// Ref: https://github.com/ant-design/ant-design/issues/7034
> i,
> span {
pointer-events: none;
}
&-primary {
.btn-primary;

View File

@ -30,6 +30,7 @@
padding: 0 @card-padding-base;
border-radius: @border-radius-sm @border-radius-sm 0 0;
.clearfix;
margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
&-title {
font-size: @font-size-lg;

View File

@ -321,7 +321,7 @@
.btn;
.btn-primary;
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; @border-radius-base);
line-height: @line-height-base;
line-height: @btn-height-sm - 2px;
&-disabled {
.button-color(@btn-disable-color; @btn-disable-bg; @btn-disable-border);

View File

@ -169,6 +169,8 @@ export default class Sider extends React.Component<SiderProps, any> {
const divStyle = {
...style,
flex: `0 0 ${siderWidth}px`,
maxWidth: `${siderWidth}px`, // Fix width transition bug in IE11
minWidth: `${siderWidth}px`, // https://github.com/ant-design/ant-design/issues/6349
width: `${siderWidth}px`,
};
const siderCls = classNames(className, prefixCls, {

View File

@ -34,7 +34,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -72,7 +72,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
</div>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -92,7 +92,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -129,7 +129,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -313,7 +313,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="overflow:auto;height:100vh;position:fixed;left:0;flex:0 0 200px;width:200px;"
style="overflow:auto;height:100vh;position:fixed;left:0;flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -578,7 +578,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -688,7 +688,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="flex:0 0 200px;width:200px;"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -1039,7 +1039,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="background:#fff;flex:0 0 200px;width:200px;"
style="background:#fff;flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"
@ -1209,7 +1209,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
>
<div
class="ant-layout-sider"
style="background:#fff;flex:0 0 200px;width:200px;"
style="background:#fff;flex:0 0 200px;max-width:200px;min-width:200px;width:200px;"
>
<div
class="ant-layout-sider-children"

View File

@ -65,6 +65,7 @@
color: @layout-trigger-color;
background: fade(@layout-trigger-background, 100);
z-index: 1;
transition: all .15s @ease-in-out;
}
&-zero-width {

View File

@ -10,35 +10,35 @@ export default {
TimePicker,
Calendar,
Table: {
filterTitle: 'Filtrar Menu',
filterConfirm: 'OK',
filterReset: 'Resetear',
emptyText: 'No Hay Datos',
selectAll: 'Seleccionar Todo',
selectInvert: 'Invertir Selección',
filterTitle: 'Filtrar menú',
filterConfirm: 'Aceptar',
filterReset: 'Reiniciar',
emptyText: 'No hay datos',
selectAll: 'Seleccionar todo',
selectInvert: 'Invertir selección',
},
Modal: {
okText: 'OK',
okText: 'Aceptar',
cancelText: 'Cancelar',
justOkText: 'OK',
justOkText: 'Aceptar',
},
Popconfirm: {
okText: 'OK',
okText: 'Aceptar',
cancelText: 'Cancelar',
},
Transfer: {
notFoundContent: 'No Encontrado',
notFoundContent: 'No encontrado',
searchPlaceholder: 'Buscar aquí',
itemUnit: 'item',
itemsUnit: 'items',
itemUnit: 'elemento',
itemsUnit: 'elementos',
},
Select: {
notFoundContent: 'No Encontrado',
notFoundContent: 'No encontrado',
},
Upload: {
uploading: 'Subiendo...',
removeFile: 'Eliminar archivo',
uploadError: 'Error de subida',
uploadError: 'Error al subir el archivo',
previewFile: 'Vista previa',
},
};

View File

@ -35,10 +35,10 @@ More layouts with navigation: [layout](/components/layout).
| defaultSelectedKeys | array with the keys of default selected menu items | string[] | |
| openKeys | array with the keys of currently opened sub menus | string[] | |
| defaultOpenKeys | array with the keys of default opened sub menus | | |
| onOpenChange | called when open/close sub menu | Function(openKeys: string[]) | noop |
| onSelect | callback of the selected item | Function({ item, key, selectedKeys }) | none |
| onDeselect | callback of the deselected item, only supported for multiple mode | Function({ item, key, selectedKeys }) | - |
| onClick | callback of the clicked menu item, params: {item, key, keyPath} | function | - |
| onOpenChange | called when open/close sub menu | function(openKeys: string[]) | noop |
| onSelect | callback of the selected item | function({ item, key, selectedKeys }) | none |
| onDeselect | callback of the deselected item, only supported for multiple mode | function({ item, key, selectedKeys }) | - |
| onClick | callback when click menu item, params: {item, key, keyPath} | function({ item, key, keyPath }) | - |
| style | style of the root node | object | |
| inlineIndent | indent px of inline menu item on each level | number | 24 |
| multiple | Allow select multiple item | boolean | false |
@ -61,7 +61,7 @@ More layouts with navigation: [layout](/components/layout).
| key | unique id of the menu item | string | |
| title | title of the sub menu | string\|ReactNode | |
| children | sub menus or sub menu items | Array<MenuItem\|SubMenu> | |
| onTitleClick | callback of the clicked sub menu title | Function({ key, domEvent }) | |
| onTitleClick | callback of the clicked sub menu title | function({ key, domEvent }) | |
### Menu.ItemGroup

View File

@ -35,10 +35,10 @@ subtitle: 导航菜单
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string[] | |
| openKeys | 当前展开的 SubMenu 菜单项 key 数组 | string[] | |
| defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | | |
| onOpenChange | SubMenu 展开/关闭的回调 | Function(openKeys: string[]) | noop |
| onSelect | 被选中时调 | Function({ item, key, selectedKeys }) | 无 |
| onDeselect | 取消选中时调用,仅在 multiple 生效 | Function({ item, key, selectedKeys }) | - |
| onClick | 点击 menuitem 调用此函数,参数为 {item, key, keyPath} | function | - |
| onOpenChange | SubMenu 展开/关闭的回调 | function(openKeys: string[]) | noop |
| onSelect | 被选中时调 | function({ item, key, selectedKeys }) | 无 |
| onDeselect | 取消选中时调用,仅在 multiple 生效 | function({ item, key, selectedKeys }) | - |
| onClick | 点击 MenuItem 调用此函数 | function({ item, key, keyPath }) | - |
| style | 根节点样式 | object | |
| inlineIndent | inline 模式的菜单缩进宽度 | number | 24 |
| multiple | 是否允许多选 | boolean | false |
@ -61,7 +61,7 @@ subtitle: 导航菜单
| key | 唯一标志 | string | |
| title | 子菜单项值 | string\|ReactNode | |
| children | 子菜单的菜单项 | Array<MenuItem\|SubMenu> | |
| onTitleClick | 点击子菜单标题 | Function({ key, domEvent }) | |
| onTitleClick | 点击子菜单标题 | function({ key, domEvent }) | |
### Menu.ItemGroup

View File

@ -2,7 +2,6 @@
@import "../../style/mixins/index";
@menu-prefix-cls: ~"@{ant-prefix}-menu";
@menu-collapsed-width: 64px;
// default theme
.@{menu-prefix-cls} {

View File

@ -1,6 +1,8 @@
import notification from '..';
describe('Notification.placement', () => {
afterEach(() => notification.destroy());
function $$(className) {
return document.body.querySelectorAll(className);
}

View File

@ -1,15 +1,43 @@
import React from 'react';
import Notification from 'rc-notification';
import Icon from '../icon';
export type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
const notificationInstance = {};
let defaultDuration = 4.5;
let defaultTop = 24;
let defaultBottom = 24;
let defaultPlacement = 'topRight';
let defaultPlacement: NotificationPlacement = 'topRight';
let defaultGetContainer;
export type notificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
function getPlacementStyle(placement) {
export interface ConfigProps {
top?: number;
bottom?: number;
duration?: number;
placement?: NotificationPlacement;
getContainer?: () => HTMLElement;
}
function setNotificationConfig(options: ConfigProps) {
const { duration, placement, bottom, top, getContainer } = options;
if (duration !== undefined) {
defaultDuration = duration;
}
if (placement !== undefined) {
defaultPlacement = placement;
}
if (bottom !== undefined) {
defaultBottom = bottom;
}
if (top !== undefined) {
defaultTop = top;
}
if (getContainer !== undefined) {
defaultGetContainer = getContainer;
}
}
function getPlacementStyle(placement: NotificationPlacement) {
let style;
switch (placement) {
case 'topLeft':
@ -19,6 +47,13 @@ function getPlacementStyle(placement) {
bottom: 'auto',
};
break;
case 'topRight':
style = {
right: 0,
top: defaultTop,
bottom: 'auto',
};
break;
case 'bottomLeft':
style = {
left: 0,
@ -26,23 +61,37 @@ function getPlacementStyle(placement) {
bottom: defaultBottom,
};
break;
case 'bottomRight':
default:
style = {
right: 0,
top: 'auto',
bottom: defaultBottom,
};
break;
default:
style = {
right: 0,
top: defaultTop,
bottom: 'auto',
};
}
return style;
}
function getNotificationInstance(prefixCls, placement) {
const cacheKey = `${prefixCls}-${placement}`;
if (!notificationInstance[cacheKey]) {
notificationInstance[cacheKey] = (Notification as any).newInstance({
prefixCls,
className: `${prefixCls}-${placement}`,
style: getPlacementStyle(placement),
getContainer: defaultGetContainer,
});
}
return notificationInstance[cacheKey];
}
const typeToIcon = {
success: 'check-circle-o',
info: 'info-circle-o',
error: 'cross-circle-o',
warning: 'exclamation-circle-o',
};
export interface ArgsProps {
message: React.ReactNode;
description: React.ReactNode;
@ -51,67 +100,18 @@ export interface ArgsProps {
onClose?: () => void;
duration?: number;
icon?: React.ReactNode;
placement?: notificationPlacement;
placement?: NotificationPlacement;
style?: string;
prefixCls?: string;
className?: string;
readonly type?: string;
}
export interface ConfigProps {
top?: number;
bottom?: number;
duration?: number;
placement?: notificationPlacement;
getContainer?: () => HTMLElement;
}
function getNotificationInstance(prefixCls) {
if (notificationInstance[defaultPlacement]) {
return notificationInstance[defaultPlacement];
}
notificationInstance[defaultPlacement] = (Notification as any).newInstance({
prefixCls: prefixCls,
className: `${prefixCls}-${defaultPlacement}`,
style: getPlacementStyle(defaultPlacement),
getContainer: defaultGetContainer,
});
return notificationInstance[defaultPlacement];
}
function notice(args) {
function notice(args: ArgsProps) {
const outerPrefixCls = args.prefixCls || 'ant-notification';
const prefixCls = `${outerPrefixCls}-notice`;
const duration = args.duration === undefined ? defaultDuration : args.duration;
if (args.placement !== undefined) {
defaultPlacement = args.placement;
}
let duration;
if (args.duration === undefined) {
duration = defaultDuration;
} else {
duration = args.duration;
}
let iconType = '';
switch (args.type) {
case 'success':
iconType = 'check-circle-o';
break;
case 'info':
iconType = 'info-circle-o';
break;
case 'error':
iconType = 'cross-circle-o';
break;
case 'warning':
iconType = 'exclamation-circle-o';
break;
default:
iconType = 'info-circle';
}
let iconNode;
let iconNode: React.ReactNode = null;
if (args.icon) {
iconNode = (
<span className={`${prefixCls}-icon`}>
@ -119,15 +119,20 @@ function notice(args) {
</span>
);
} else if (args.type) {
iconNode = <Icon className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`} type={iconType} />;
const iconType = typeToIcon[args.type];
iconNode = (
<Icon
className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`}
type={iconType}
/>
);
}
const autoMarginTag = (!args.description && iconNode)
? <span className={`${prefixCls}-message-single-line-auto-margin`} />
: null;
const { style, className } = args;
getNotificationInstance(outerPrefixCls).notice({
getNotificationInstance(outerPrefixCls, args.placement || defaultPlacement).notice({
content: (
<div className={iconNode ? `${prefixCls}-with-icon` : ''}>
{iconNode}
@ -143,11 +148,35 @@ function notice(args) {
closable: true,
onClose: args.onClose,
key: args.key,
style: { ...style },
className,
style: args.style || {},
className: args.className,
});
}
const api: any = {
open: notice,
close(key) {
Object.keys(notificationInstance)
.forEach(cacheKey => notificationInstance[cacheKey].removeNotice(key));
},
config: setNotificationConfig,
destroy() {
Object.keys(notificationInstance).forEach(cacheKey => {
notificationInstance[cacheKey].destroy();
delete notificationInstance[cacheKey];
});
},
};
['success', 'info', 'warning', 'error'].forEach((type) => {
api[type] = (args: ArgsProps) => api.open({
...args,
type,
});
});
api.warn = api.warning;
export interface NotificationApi {
success(args: ArgsProps): void;
error(args: ArgsProps): void;
@ -159,57 +188,4 @@ export interface NotificationApi {
config(options: ConfigProps): void;
destroy(): void;
}
const api = {
open(args: ArgsProps) {
notice(args);
},
close(key) {
if (notificationInstance[defaultPlacement]) {
notificationInstance[defaultPlacement].removeNotice(key);
}
},
config(options: ConfigProps) {
const { duration, placement, bottom, top, getContainer } = options;
if (placement !== undefined) {
defaultPlacement = placement;
}
if (bottom !== undefined) {
defaultBottom = bottom;
}
if (top !== undefined) {
defaultTop = top;
}
if (getContainer !== undefined) {
defaultGetContainer = getContainer;
}
// delete notificationInstance
if (placement !== undefined || bottom !== undefined || top !== undefined) {
const notify = notificationInstance[defaultPlacement];
if (notify) {
notify.destroy();
}
delete notificationInstance[defaultPlacement];
}
if (duration !== undefined) {
defaultDuration = duration;
}
},
destroy() {
Object.keys(notificationInstance).forEach(key => {
notificationInstance[key].destroy();
delete notificationInstance[key];
});
},
};
['success', 'info', 'warning', 'error'].forEach((type) => {
api[type] = (args: ArgsProps) => api.open({
...args,
type,
});
});
(api as any).warn = (api as any).warning;
export default api as NotificationApi;

View File

@ -187,7 +187,8 @@
}
&-disabled {
&:hover {
&:hover,
&:focus {
border-color: @border-color-base;
a {
color: @disabled-color;

View File

@ -853,7 +853,7 @@ exports[`renders ./components/select/demo/tags.md correctly 1`] = `
style="display:block;user-select:none;-webkit-user-select:none;"
unselectable="unselectable"
>
标签模式
Tags Mode
</div>
<ul>
<li

View File

@ -30,7 +30,7 @@ ReactDOM.render(
<Select
mode="tags"
style={{ width: '100%' }}
placeholder="标签模式"
placeholder="Tags Mode"
onChange={handleChange}
>
{children}

View File

@ -67,8 +67,7 @@ export interface SelectContext {
};
}
export const SelectPropTypes = {
...RcSelect.propTypes,
const SelectPropTypes = {
prefixCls: PropTypes.string,
className: PropTypes.string,
size: PropTypes.oneOf(['default', 'large', 'small']),

View File

@ -288,6 +288,7 @@
// ---
@menu-dark-bg: @layout-header-background;
@menu-dark-submenu-bg: #333;
@menu-collapsed-width: 64px;
// Spin
// ---

View File

@ -141,7 +141,7 @@ import { Table } from 'antd';
import { TableColumnConfig } from 'antd/lib/table/Table';
interface IUser {
key: number,
key: number;
name: string;
}

View File

@ -97,6 +97,7 @@ exports[`renders ./components/tabs/demo/basic.md correctly 1`] = `
exports[`renders ./components/tabs/demo/card.md correctly 1`] = `
<div
class="ant-tabs ant-tabs-top ant-tabs-card ant-tabs-no-animation"
type="card"
>
<div
class="ant-tabs-bar"
@ -193,6 +194,7 @@ exports[`renders ./components/tabs/demo/card-top.md correctly 1`] = `
>
<div
class="ant-tabs ant-tabs-top ant-tabs-card ant-tabs-no-animation"
type="card"
>
<div
class="ant-tabs-bar"
@ -308,6 +310,7 @@ exports[`renders ./components/tabs/demo/custom-add-trigger.md correctly 1`] = `
</div>
<div
class="ant-tabs ant-tabs-top ant-tabs-card ant-tabs-editable-card ant-tabs-no-animation"
type="editable-card"
>
<div
class="ant-tabs-bar"
@ -479,6 +482,7 @@ exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = `
<div
aria-hidden="true"
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
disabled=""
role="tabpanel"
/>
<div
@ -493,6 +497,7 @@ exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = `
exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = `
<div
class="ant-tabs ant-tabs-top ant-tabs-card ant-tabs-editable-card ant-tabs-no-animation"
type="editable-card"
>
<div
class="ant-tabs-bar"

View File

@ -22,6 +22,7 @@ exports[`Tabs tabPosition remove card 1`] = `
>
<div
className="ant-tabs ant-tabs-left ant-tabs-vertical ant-tabs-line"
onChange={[Function]}
style={Object {}}
>
<ScrollableInkTabBar
@ -59,11 +60,11 @@ exports[`Tabs tabPosition remove card 1`] = `
>
<div
className="ant-tabs-nav-container"
onTransitionEnd={[Function]}
>
<span
className="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
onClick={null}
onTransitionEnd={[Function]}
unselectable="unselectable"
>
<span

View File

@ -26,7 +26,7 @@
border-bottom: @border-width-base @border-style-base @border-color-base;
margin-bottom: 16px;
outline: none;
transition: padding .45s;
transition: padding .3s @ease-in-out;
}
&-nav-container {
@ -37,7 +37,7 @@
position: relative;
white-space: nowrap;
margin-bottom: -1px;
transition: padding .45s;
transition: padding .3s @ease-in-out;
.clearfix;
&-scrolling {
@ -51,7 +51,7 @@
user-select: none;
z-index: 2;
width: 0;
height: 0;
height: 100%;
line-height: 32px;
cursor: pointer;
border: 0;
@ -59,7 +59,7 @@
position: absolute;
text-align: center;
color: @text-color-secondary;
transition: width .3s, height .3s, opacity .3s, color .3s;
transition: width .3s @ease-in-out, opacity .3s @ease-in-out, color .3s @ease-in-out;
opacity: 0;
pointer-events: none;
@ -134,7 +134,7 @@
&-nav {
box-sizing: border-box;
padding-left: 0;
transition: transform 0.5s @ease-in-out;
transition: transform 0.3s @ease-in-out;
position: relative;
margin: 0;
list-style: none;
@ -230,7 +230,11 @@
> .@{tab-prefix-cls}-bar {
border-bottom: 0;
height: 100%;
&-tab-prev, &-tab-next {
width: 32px;
height: 0;
transition: height .3s @ease-in-out, opacity .3s @ease-in-out, color .3s @ease-in-out;
}
&-tab-prev.@{tab-prefix-cls}-tab-arrow-show,
&-tab-next.@{tab-prefix-cls}-tab-arrow-show {
width: 100%;

View File

@ -12,7 +12,7 @@
border: @border-width-base @border-style-base @border-color-split;
background: @tag-default-bg;
font-size: @tag-font-size;
transition: all 0.3s @ease-in-out-circ;
transition: all 0.3s @ease-out;
opacity: 1;
margin-right: 8px;
cursor: pointer;
@ -41,7 +41,7 @@
cursor: pointer;
font-weight: bold;
margin-left: 3px;
transition: all 0.3s ease;
transition: all 0.3s @ease-out;
opacity: 0.66;
&:hover {

View File

@ -24,7 +24,7 @@ export default class Timeline extends React.Component<TimelineProps, any> {
}, className);
const items = React.Children.map(children, (ele: React.ReactElement<any>, idx) =>
React.cloneElement(ele, {
last: idx === (children as { length: number }).length - 1,
last: idx === (React.Children.count(children) - 1),
}),
);
const pendingItem = (!!pending) ? (

View File

@ -26,7 +26,7 @@ We supply a series of design principles, practical patterns and high quality des
[React](http://facebook.github.io/react/) is used to encapsulate a library of Ant Design components. Any other version of frameworks to implement is also welcome.
- [Ant Design of React](/docs/react/introduce) (official implementation)
- <div class="outside-link internal"><a href="http://zorro.alibaba.net" target="_blank">Ant Design of Angular 2</a></div>
- <div class="outside-link"><a href="http://ng.ant.design" target="_blank">NG-ZORRO - Ant Design of Angular</a></div>
- <div class="outside-link"><a href="https://github.com/iview/iview/" target="_blank">iView (vue)</a></div>
- <div class="outside-link"><a href="https://github.com/FE-Driver/vue-beauty" target="_blank">vue-beauty</a></div>
- <div class="outside-link"><a href="https://github.com/aliqin/atui" target="_blank">ATUI (vue)</a></div>

View File

@ -26,7 +26,7 @@ Ant Design 是一个致力于提升『用户』和『设计者』使用体验的
我们采用 [React](http://facebook.github.io/react/) 封装了一套 Ant Design 的组件库,也欢迎社区其他框架的实现版本。
- [Ant Design of React](/docs/react/introduce)(官方实现)
- <div class="outside-link internal"><a href="http://zorro.alibaba.net" target="_blank">Ant Design of Angular 2</a></div>
- <div class="outside-link"><a href="http://ng.ant.design" target="_blank">NG-ZORRO - Ant Design of Angular</a></div>
- <div class="outside-link"><a href="https://github.com/iview/iview/" target="_blank">iView (vue)</a></div>
- <div class="outside-link"><a href="https://github.com/FE-Driver/vue-beauty" target="_blank">vue-beauty</a></div>
- <div class="outside-link"><a href="https://github.com/aliqin/atui" target="_blank">ATUI (vue)</a></div>

View File

@ -65,7 +65,7 @@
"rc-steps": "~2.5.1",
"rc-switch": "~1.5.1",
"rc-table": "~5.4.0",
"rc-tabs": "~9.0.2",
"rc-tabs": "~9.1.2",
"rc-time-picker": "~2.4.1",
"rc-tooltip": "~3.4.6",
"rc-tree": "~1.7.0",

View File

@ -127,14 +127,18 @@
position: absolute;
left: 0;
top: 0;
&:hover {
opacity: 1;
}
}
.code-expand-icon-show {
opacity: 0.55;
pointer-events: auto;
&:hover {
opacity: 1;
}
}
.code-expand-icon.ant-tooltip-open .code-expand-icon-show {
opacity: 1;
}
.code-expand-icon-hide {

View File

@ -36,8 +36,8 @@ export default class Demo extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return (this.state.codeExpand || this.props.expand) !== (nextState.codeExpand || nextProps.expand)
|| this.state.copied !== nextState.copied
|| this.state.copyTooltipVisible !== nextState.copyTooltipVisible;
|| this.state.copied !== nextState.copied
|| this.state.copyTooltipVisible !== nextState.copyTooltipVisible;
}
componentDidMount() {
@ -176,7 +176,8 @@ export default class Demo extends React.Component {
</span>
</Tooltip>
</section>
<section className={highlightClass}
<section
className={highlightClass}
key="code"
>
<div className="highlight">

View File

@ -61,20 +61,9 @@ export default class MainContent extends React.Component {
if (!location.hash) {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
} else {
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
document.getElementById(decodeURI(location.hash.replace('#', ''))).scrollIntoView();
}, 10);
}
}
componentWillUnmount() {
clearTimeout(this.timer);
}
handleMenuOpenChange = (openKeys) => {
this.setState({ openKeys });
}

View File

@ -69,16 +69,16 @@ class Footer extends React.Component {
</li>
<li>
<h2><Icon type="link" /> <FormattedMessage id="app.footer.links" /></h2>
<div>
<a href="https://design.alipay.com/">
<FormattedMessage id="app.footer.design-platform" />
</a>
</div>
<div>
<a href="http://mobile.ant.design">Ant Design Mobile</a>
<span> - </span>
<FormattedMessage id="app.footer.mobile" />
</div>
<div>
<a href="http://ng.ant.design">NG-ZORRO</a>
<span> - </span>
Ant Design of Angular
</div>
<div>
<a href="http://scaffold.ant.design">Scaffolds</a>
<span> - </span>