refactor: 保证所有的tsx和less都正确使用prefix (#3024)

* refactor: extract prefix cls as less variable

* refactor: apply ant icon prefix cls in less files

* refactor: all components support prefixCls props
This commit is contained in:
马斯特 2016-09-14 16:18:33 +08:00 committed by Benjy Cui
parent 7a7395329b
commit a25ec29fb8
75 changed files with 395 additions and 335 deletions

View File

@ -55,6 +55,7 @@ export interface AffixProps {
style?: React.CSSProperties; style?: React.CSSProperties;
onChange?: (affixed?: boolean) => any; onChange?: (affixed?: boolean) => any;
target?: () => Window | HTMLElement; target?: () => Window | HTMLElement;
prefixCls?: string;
} }
export default class Affix extends React.Component<AffixProps, any> { export default class Affix extends React.Component<AffixProps, any> {
@ -69,6 +70,7 @@ export default class Affix extends React.Component<AffixProps, any> {
return window; return window;
}, },
onChange() {}, onChange() {},
prefixCls: 'ant-affix',
}; };
scrollEvent: any; scrollEvent: any;
@ -215,7 +217,7 @@ export default class Affix extends React.Component<AffixProps, any> {
render() { render() {
const className = classNames({ const className = classNames({
'ant-affix': this.state.affixStyle, [this.props.prefixCls]: this.state.affixStyle,
}); });
const props = assign({}, this.props); const props = assign({}, this.props);

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
.ant-affix { .@{ant-prefix}-affix {
position: fixed; position: fixed;
z-index: @zindex-affix; z-index: @zindex-affix;
} }

View File

@ -113,7 +113,7 @@ export default class Alert extends React.Component<AlertProps, any> {
onEnd={this.animationEnd} onEnd={this.animationEnd}
> >
<div data-show={this.state.closing} className={alertCls}> <div data-show={this.state.closing} className={alertCls}>
{showIcon ? <Icon className="ant-alert-icon" type={iconType} /> : null} {showIcon ? <Icon className={`${prefixCls}-icon`} type={iconType} /> : null}
<span className={`${prefixCls}-message`}>{message}</span> <span className={`${prefixCls}-message`}>{message}</span>
<span className={`${prefixCls}-description`}>{description}</span> <span className={`${prefixCls}-description`}>{description}</span>
{closable ? <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}> {closable ? <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@alert-prefix-cls: ant-alert; @alert-prefix-cls: ~"@{ant-prefix}-alert";
.@{alert-prefix-cls} { .@{alert-prefix-cls} {
position: relative; position: relative;
@ -70,7 +70,7 @@
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
.anticon-cross { .@{iconfont-css-prefix}-cross {
color: @legend-color; color: @legend-color;
transition: color .3s ease; transition: color .3s ease;
&:hover { &:hover {

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@backtop-prefix-cls: ant-back-top; @backtop-prefix-cls: ~"@{ant-prefix}-back-top";
.@{backtop-prefix-cls} { .@{backtop-prefix-cls} {
z-index: @zindex-back-top; z-index: @zindex-back-top;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@badge-prefix-cls: ant-badge; @badge-prefix-cls: ~"@{ant-prefix}-badge";
@number-prefix-cls: ant-scroll-number; @number-prefix-cls: ~"@{ant-prefix}-scroll-number";
.@{badge-prefix-cls} { .@{badge-prefix-cls} {
position: relative; position: relative;

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@breadcrumb-prefix-cls: ant-breadcrumb; @breadcrumb-prefix-cls: ~"@{ant-prefix}-breadcrumb";
.@{breadcrumb-prefix-cls} { .@{breadcrumb-prefix-cls} {
color: #999; color: #999;
@ -29,7 +29,7 @@
} }
&-link { &-link {
> .anticon + span { > .@{iconfont-css-prefix} + span {
margin-left: 4px; margin-left: 4px;
} }
} }

View File

@ -2,18 +2,18 @@ import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import splitObject from '../_util/splitObject'; import splitObject from '../_util/splitObject';
const prefix = 'ant-btn-group-';
export type ButtonSize = 'small' | 'large' export type ButtonSize = 'small' | 'large'
export interface ButtonGroupProps { export interface ButtonGroupProps {
size?: ButtonSize; size?: ButtonSize;
style?: React.CSSProperties; style?: React.CSSProperties;
className?: string; className?: string;
prefixCls?: string;
} }
export default function ButtonGroup(props: ButtonGroupProps) { export default function ButtonGroup(props: ButtonGroupProps) {
const [{ size, className }, others] = splitObject(props, ['size', 'className']); const [{ prefixCls = 'ant-btn-group', size, className }, others] =
splitObject(props, ['prefixCls', 'size', 'className']);
// large => lg // large => lg
// small => sm // small => sm
@ -23,8 +23,8 @@ export default function ButtonGroup(props: ButtonGroupProps) {
})[size] || ''; })[size] || '';
const classes = classNames({ const classes = classNames({
'ant-btn-group': true, [prefixCls]: true,
[prefix + sizeCls]: sizeCls, [`${prefixCls}-${sizeCls}`]: sizeCls,
[className]: className, [className]: className,
}); });

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "./mixin"; @import "./mixin";
@btn-prefix-cls: ant-btn; @btn-prefix-cls: ~"@{ant-prefix}-btn";
// Button styles // Button styles
// ----------------------------- // -----------------------------
@ -69,7 +69,7 @@
padding-left: 29px; padding-left: 29px;
pointer-events: none; pointer-events: none;
position: relative; position: relative;
.anticon { .@{iconfont-css-prefix} {
margin-left: -14px; margin-left: -14px;
transition: all .3s @ease-in-out; transition: all .3s @ease-in-out;
} }
@ -80,7 +80,7 @@
&-sm&-loading { &-sm&-loading {
padding-left: 24px; padding-left: 24px;
.anticon { .@{iconfont-css-prefix} {
margin-left: -17px; margin-left: -17px;
} }
} }

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@full-calendar-prefix-cls: ant-fullcalendar; @full-calendar-prefix-cls: ~"@{ant-prefix}-fullcalendar";
.@{full-calendar-prefix-cls} { .@{full-calendar-prefix-cls} {
font-size: @font-size-base; font-size: @font-size-base;
@ -14,16 +14,16 @@
padding: 11px 16px 11px 0; padding: 11px 16px 11px 0;
text-align: right; text-align: right;
.ant-select { .@{ant-prefix}-select {
text-align: left; text-align: left;
} }
.ant-radio-group { .@{ant-prefix}-radio-group {
margin-left: 8px; margin-left: 8px;
text-align: left; text-align: left;
} }
label.ant-radio-button { label.@{ant-prefix}-radio-button {
height: 22px; height: 22px;
line-height: 20px; line-height: 20px;
padding: 0 10px; padding: 0 10px;
@ -162,10 +162,10 @@
} }
&-fullscreen &-header { &-fullscreen &-header {
.ant-radio-group { .@{ant-prefix}-radio-group {
margin-left: 16px; margin-left: 16px;
} }
label.ant-radio-button { label.@{ant-prefix}-radio-button {
height: 28px; height: 28px;
line-height: 26px; line-height: 26px;
} }

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@card-prefix-cls: ant-card; @card-prefix-cls: ~"@{ant-prefix}-card";
.@{card-prefix-cls} { .@{card-prefix-cls} {
background: #fff; background: #fff;

View File

@ -37,12 +37,14 @@ export interface CarouselProps {
afterChange?: (current: number) => void; afterChange?: (current: number) => void;
/** 行内样式 */ /** 行内样式 */
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string;
} }
export default class Carousel extends React.Component<CarouselProps, any> { export default class Carousel extends React.Component<CarouselProps, any> {
static defaultProps = { static defaultProps = {
dots: true, dots: true,
arrows: false, arrows: false,
prefixCls: 'ant-carousel',
}; };
render() { render() {
@ -53,9 +55,9 @@ export default class Carousel extends React.Component<CarouselProps, any> {
props.draggable = false; props.draggable = false;
} }
let className = 'ant-carousel'; let className = props.prefixCls;
if (props.vertical) { if (props.vertical) {
className = `${className} ant-carousel-vertical`; className = `${className} ${className}-vertical`;
} }
return ( return (

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
.ant-carousel { .@{ant-prefix}-carousel {
.slick-slider { .slick-slider {
position: relative; position: relative;
display: block; display: block;
@ -204,7 +204,7 @@
} }
} }
.ant-carousel-vertical { .@{ant-prefix}-carousel-vertical {
.slick-slider { .slick-slider {
padding-bottom: 0; padding-bottom: 0;
} }

View File

@ -18,7 +18,7 @@ export type CascaderExpandTrigger = 'click' | 'hover'
export interface ShowSearchType { export interface ShowSearchType {
filter?: (inputValue: string, path: CascaderOptionType[]) => boolean; filter?: (inputValue: string, path: CascaderOptionType[]) => boolean;
render?: (inputValue: string, path: CascaderOptionType[]) => React.ReactNode; render?: (inputValue: string, path: CascaderOptionType[], prefixCls: string) => React.ReactNode;
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number; sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number;
matchInputWidth?: boolean; matchInputWidth?: boolean;
} }
@ -58,12 +58,14 @@ export interface CascaderProps {
changeOnSelect?: boolean; changeOnSelect?: boolean;
/** 浮层可见变化时回调 */ /** 浮层可见变化时回调 */
onPopupVisibleChange?: (popupVisible: boolean) => void; onPopupVisibleChange?: (popupVisible: boolean) => void;
prefixCls?: string;
inputPrefixCls?: string;
} }
function highlightKeyword(str: string, keyword: string) { function highlightKeyword(str: string, keyword: string, prefixCls: string) {
return str.split(keyword) return str.split(keyword)
.map((node: string, index: number) => index === 0 ? node : [ .map((node: string, index: number) => index === 0 ? node : [
<span className="ant-cascader-menu-item-keyword" key="seperator">{keyword}</span>, <span className={`${prefixCls}-menu-item-keyword`} key="seperator">{keyword}</span>,
node, node,
]); ]);
} }
@ -72,9 +74,9 @@ function defaultFilterOption(inputValue, path) {
return path.some(option => option.label.indexOf(inputValue) > -1); return path.some(option => option.label.indexOf(inputValue) > -1);
} }
function defaultRenderFilteredOption(inputValue, path) { function defaultRenderFilteredOption(inputValue, path, prefixCls) {
return path.map(({ label }, index) => { return path.map(({ label }, index) => {
const node = label.indexOf(inputValue) > -1 ? highlightKeyword(label, inputValue) : label; const node = label.indexOf(inputValue) > -1 ? highlightKeyword(label, inputValue, prefixCls) : label;
return index === 0 ? node : [' / ', node]; return index === 0 ? node : [' / ', node];
}); });
} }
@ -90,6 +92,7 @@ function defaultSortFilteredOption(a, b, inputValue) {
export default class Cascader extends React.Component<CascaderProps, any> { export default class Cascader extends React.Component<CascaderProps, any> {
static defaultProps = { static defaultProps = {
prefixCls: 'ant-cascader', prefixCls: 'ant-cascader',
inputPrefixCls: 'ant-input',
placeholder: 'Please select', placeholder: 'Please select',
transitionName: 'slide-up', transitionName: 'slide-up',
popupPlacement: 'bottomLeft', popupPlacement: 'bottomLeft',
@ -206,7 +209,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
return flattenOptions; return flattenOptions;
} }
generateFilteredOptions() { generateFilteredOptions(prefixCls) {
const { showSearch, notFoundContent } = this.props; const { showSearch, notFoundContent } = this.props;
const { const {
filter = defaultFilterOption, filter = defaultFilterOption,
@ -220,7 +223,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
if (filtered.length > 0) { if (filtered.length > 0) {
return filtered.map((path) => { return filtered.map((path) => {
return { return {
label: render(inputValue, path), label: render(inputValue, path, prefixCls),
value: path.map(o => o.value), value: path.map(o => o.value),
}; };
}); });
@ -238,8 +241,8 @@ export default class Cascader extends React.Component<CascaderProps, any> {
const value = state.value; const value = state.value;
const sizeCls = classNames({ const sizeCls = classNames({
'ant-input-lg': size === 'large', [`${props.inputPrefixCls}-lg`]: size === 'large',
'ant-input-sm': size === 'small', [`${props.inputPrefixCls}-sm`]: size === 'small',
}); });
const clearIcon = (allowClear && !disabled && value.length > 0) || state.inputValue ? const clearIcon = (allowClear && !disabled && value.length > 0) || state.inputValue ?
<Icon type="cross-circle" <Icon type="cross-circle"
@ -279,7 +282,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
let options = props.options; let options = props.options;
if (state.inputValue) { if (state.inputValue) {
options = this.generateFilteredOptions(); options = this.generateFilteredOptions(prefixCls);
} }
// Dropdown menu should keep previous status until it is fully closed. // Dropdown menu should keep previous status until it is fully closed.
if (!state.popupVisible) { if (!state.popupVisible) {

View File

@ -1,11 +1,11 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@cascader-prefix-cls: ant-cascader; @cascader-prefix-cls: ~"@{ant-prefix}-cascader";
.@{cascader-prefix-cls} { .@{cascader-prefix-cls} {
font-size: @font-size-base; font-size: @font-size-base;
&-input.ant-input { &-input.@{ant-prefix}-input {
background-color: transparent; background-color: transparent;
display: block; display: block;
cursor: pointer; cursor: pointer;

View File

@ -19,6 +19,7 @@ export interface CheckboxGroupProps {
onChange?: (checkedValue: Array<string>) => void; onChange?: (checkedValue: Array<string>) => void;
disabled?: boolean; disabled?: boolean;
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string;
} }
export interface CheckboxGroupState { export interface CheckboxGroupState {
@ -30,6 +31,7 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
options: [], options: [],
defaultValue: [], defaultValue: [],
onChange() {}, onChange() {},
prefixCls: 'ant-checkbox-group',
}; };
static propTypes = { static propTypes = {
defaultValue: React.PropTypes.array, defaultValue: React.PropTypes.array,
@ -84,15 +86,16 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
this.props.onChange(value); this.props.onChange(value);
} }
render() { render() {
const { prefixCls } = this.props;
const options = this.getOptions(); const options = this.getOptions();
return ( return (
<div className="ant-checkbox-group"> <div className={prefixCls}>
{ {
options.map(option => options.map(option =>
<Checkbox disabled={'disabled' in option ? option.disabled : this.props.disabled} <Checkbox disabled={'disabled' in option ? option.disabled : this.props.disabled}
checked={this.state.value.indexOf(option.value) !== -1} checked={this.state.value.indexOf(option.value) !== -1}
onChange={() => this.toggleOption(option)} onChange={() => this.toggleOption(option)}
className="ant-checkbox-group-item" key={option.value} className={`${prefixCls}-item`} key={option.value}
> >
{option.label} {option.label}
</Checkbox> </Checkbox>

View File

@ -1,6 +1,6 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
.antCheckboxFn(@checkbox-prefix-cls: ant-checkbox) { .antCheckboxFn(@checkbox-prefix-cls: ~"@{ant-prefix}-checkbox") {
@checkbox-inner-prefix-cls: ~"@{checkbox-prefix-cls}-inner"; @checkbox-inner-prefix-cls: ~"@{checkbox-prefix-cls}-inner";
// 一般状态 // 一般状态
.@{checkbox-prefix-cls} { .@{checkbox-prefix-cls} {

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@collapse-prefix-cls: ant-collapse; @collapse-prefix-cls: ~"@{ant-prefix}-collapse";
.collapse-close() { .collapse-close() {
.iconfont-size-under-12px(7px, 270deg); .iconfont-size-under-12px(7px, 270deg);

View File

@ -8,6 +8,7 @@ import Icon from '../icon';
export default class RangePicker extends React.Component<any, any> { export default class RangePicker extends React.Component<any, any> {
static defaultProps = { static defaultProps = {
defaultValue: [], defaultValue: [],
prefixCls: 'ant-calendar',
}; };
constructor(props) { constructor(props) {
@ -50,12 +51,12 @@ export default class RangePicker extends React.Component<any, any> {
const props = this.props; const props = this.props;
const locale = props.locale; const locale = props.locale;
const { disabledDate, showTime, getCalendarContainer, const { disabledDate, showTime, getCalendarContainer, prefixCls,
transitionName, disabled, popupStyle, align, style, onOk } = this.props; transitionName, disabled, popupStyle, align, style, onOk } = this.props;
const state = this.state; const state = this.state;
const calendarClassName = classNames({ const calendarClassName = classNames({
'ant-calendar-time': showTime, [`${prefixCls}-time`]: showTime,
}); });
// 需要选择时间时,点击 ok 时才触发 onChange // 需要选择时间时,点击 ok 时才触发 onChange
@ -81,7 +82,7 @@ export default class RangePicker extends React.Component<any, any> {
const calendar = ( const calendar = (
<RangeCalendar <RangeCalendar
{...calendarHandler} {...calendarHandler}
prefixCls="ant-calendar" prefixCls={prefixCls}
className={calendarClassName} className={calendarClassName}
timePicker={props.timePicker} timePicker={props.timePicker}
disabledDate={disabledDate} disabledDate={disabledDate}
@ -95,7 +96,7 @@ export default class RangePicker extends React.Component<any, any> {
const clearIcon = (!props.disabled && state.value && (state.value[0] || state.value[1])) const clearIcon = (!props.disabled && state.value && (state.value[0] || state.value[1]))
? <Icon ? <Icon
type="cross-circle" type="cross-circle"
className="ant-calendar-picker-clear" className={`${prefixCls}-picker-clear`}
onClick={this.clearSelection} onClick={this.clearSelection}
/> : null; /> : null;
@ -106,7 +107,7 @@ export default class RangePicker extends React.Component<any, any> {
disabled={disabled} disabled={disabled}
calendar={calendar} calendar={calendar}
value={state.value} value={state.value}
prefixCls="ant-calendar-picker-container" prefixCls={`${prefixCls}-picker-container`}
style={popupStyle} style={popupStyle}
align={align} align={align}
getCalendarContainer={getCalendarContainer} getCalendarContainer={getCalendarContainer}
@ -124,18 +125,18 @@ export default class RangePicker extends React.Component<any, any> {
readOnly readOnly
value={(start && start.format(props.format)) || ''} value={(start && start.format(props.format)) || ''}
placeholder={startPlaceholder} placeholder={startPlaceholder}
className="ant-calendar-range-picker-input" className={`${prefixCls}-range-picker-input`}
/> />
<span className="ant-calendar-range-picker-separator"> ~ </span> <span className={`${prefixCls}-range-picker-separator`}> ~ </span>
<input <input
disabled={disabled} disabled={disabled}
readOnly readOnly
value={(end && end.format(props.format)) || ''} value={(end && end.format(props.format)) || ''}
placeholder={endPlaceholder} placeholder={endPlaceholder}
className="ant-calendar-range-picker-input" className={`${prefixCls}-range-picker-input`}
/> />
{clearIcon} {clearIcon}
<span className="ant-calendar-picker-icon" /> <span className={`${prefixCls}-picker-icon`} />
</span> </span>
); );
} }

View File

@ -8,11 +8,17 @@ import Icon from '../icon';
export interface PickerProps { export interface PickerProps {
value?: moment.Moment; value?: moment.Moment;
prefixCls: string;
} }
export default function createPicker(TheCalendar) { export default function createPicker(TheCalendar) {
// use class typescript error // use class typescript error
const CalenderWrapper = React.createClass({ const CalenderWrapper = React.createClass({
getDefaultProps() {
return {
prefixCls: 'ant-calendar',
};
},
getInitialState() { getInitialState() {
const props = this.props; const props = this.props;
@ -46,6 +52,7 @@ export default function createPicker(TheCalendar) {
render() { render() {
const props = this.props; const props = this.props;
const prefixCls = props.prefixCls;
const locale = props.locale; const locale = props.locale;
const placeholder = ('placeholder' in props) const placeholder = ('placeholder' in props)
@ -54,8 +61,8 @@ export default function createPicker(TheCalendar) {
const disabledTime = props.showTime ? props.disabledTime : null; const disabledTime = props.showTime ? props.disabledTime : null;
const calendarClassName = classNames({ const calendarClassName = classNames({
'ant-calendar-time': props.showTime, [`${prefixCls}-time`]: props.showTime,
'ant-calendar-month': MonthCalendar === TheCalendar, [`${prefixCls}-month`]: MonthCalendar === TheCalendar,
}); });
// 需要选择时间时,点击 ok 时才触发 onChange // 需要选择时间时,点击 ok 时才触发 onChange
@ -85,7 +92,7 @@ export default function createPicker(TheCalendar) {
timePicker={props.timePicker} timePicker={props.timePicker}
defaultValue={props.defaultPickerValue || moment()} defaultValue={props.defaultPickerValue || moment()}
dateInputPlaceholder={placeholder} dateInputPlaceholder={placeholder}
prefixCls="ant-calendar" prefixCls={prefixCls}
className={calendarClassName} className={calendarClassName}
onOk={props.onOk} onOk={props.onOk}
{...calendarHandler} {...calendarHandler}
@ -100,7 +107,7 @@ export default function createPicker(TheCalendar) {
const clearIcon = (!props.disabled && this.state.value) ? const clearIcon = (!props.disabled && this.state.value) ?
<Icon type="cross-circle" <Icon type="cross-circle"
className="ant-calendar-picker-clear" className={`${prefixCls}-picker-clear`}
onClick={this.clearSelection} onClick={this.clearSelection}
/> : null; /> : null;
return ( return (
@ -111,7 +118,7 @@ export default function createPicker(TheCalendar) {
disabled={props.disabled} disabled={props.disabled}
calendar={calendar} calendar={calendar}
value={this.state.value} value={this.state.value}
prefixCls="ant-calendar-picker-container" prefixCls={`${prefixCls}-picker-container`}
style={props.popupStyle} style={props.popupStyle}
align={props.align} align={props.align}
getCalendarContainer={props.getCalendarContainer} getCalendarContainer={props.getCalendarContainer}
@ -131,7 +138,7 @@ export default function createPicker(TheCalendar) {
className={props.pickerInputClass} className={props.pickerInputClass}
/> />
{clearIcon} {clearIcon}
<span className="ant-calendar-picker-icon" /> <span className={`${prefixCls}-picker-icon`} />
</span> </span>
); );
} }

View File

@ -17,6 +17,8 @@ export interface PickerProps {
locale?: any; locale?: any;
size?: 'large' | 'small' | 'default'; size?: 'large' | 'small' | 'default';
getCalendarContainer?: (trigger) => React.ReactNode; getCalendarContainer?: (trigger) => React.ReactNode;
prefixCls?: string;
inputPrefixCls?: string;
} }
export interface SinglePickerProps { export interface SinglePickerProps {

View File

@ -1,6 +1,6 @@
@input-box-height: 34px; @input-box-height: 34px;
.@{calendar-prefix-cls}-range-picker.ant-input { .@{calendar-prefix-cls}-range-picker.@{ant-prefix}-input {
padding-right: 26px; padding-right: 26px;
} }

View File

@ -3,8 +3,8 @@
@import "../../input/style/mixin"; @import "../../input/style/mixin";
@import "../../button/style/mixin"; @import "../../button/style/mixin";
@calendar-prefix-cls: ant-calendar; @calendar-prefix-cls: ~"@{ant-prefix}-calendar";
@timepicker-prefix-cls: ant-calendar-time-picker; @timepicker-prefix-cls: ~"@{ant-prefix}-calendar-time-picker";
@import "Picker"; @import "Picker";
@import "Calendar"; @import "Calendar";

View File

@ -22,6 +22,8 @@ export default function wrapPicker(Picker, defaultFormat?) {
align: { align: {
offset: [0, -9], offset: [0, -9],
}, },
prefixCls: 'ant-calendar',
inputPrefixCls: 'ant-input',
}; };
}, },
@ -48,14 +50,15 @@ export default function wrapPicker(Picker, defaultFormat?) {
render() { render() {
const props = this.props; const props = this.props;
const { prefixCls, inputPrefixCls } = props;
const pickerClass = classNames({ const pickerClass = classNames({
'ant-calendar-picker': true, [`${prefixCls}-picker`]: true,
}); });
const pickerInputClass = classNames({ const pickerInputClass = classNames({
'ant-calendar-range-picker': true, [`${prefixCls}-range-picker`]: true,
'ant-input': true, [inputPrefixCls]: true,
'ant-input-lg': props.size === 'large', [`${inputPrefixCls}-lg`]: props.size === 'large',
'ant-input-sm': props.size === 'small', [`${inputPrefixCls}-sm`]: props.size === 'small',
}); });
const locale = this.getLocale(); const locale = this.getLocale();
@ -70,7 +73,7 @@ export default function wrapPicker(Picker, defaultFormat?) {
<TimePickerPanel <TimePickerPanel
{...rcTimePickerProps} {...rcTimePickerProps}
{...props.showTime} {...props.showTime}
prefixCls="ant-calendar-time-picker" prefixCls={`${prefixCls}-time-picker`}
placeholder={locale.timePickerLocale.placeholder} placeholder={locale.timePickerLocale.placeholder}
transitionName="slide-up" transitionName="slide-up"
/> />

View File

@ -14,6 +14,7 @@ export interface DropdownButtonProps {
visible?: boolean; visible?: boolean;
onVisibleChange?: (visible: boolean) => void; onVisibleChange?: (visible: boolean) => void;
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string;
} }
export default class DropdownButton extends React.Component<DropdownButtonProps, any> { export default class DropdownButton extends React.Component<DropdownButtonProps, any> {
@ -28,13 +29,15 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
targetOffset: [0, 0], targetOffset: [0, 0],
}, },
type: 'default', type: 'default',
prefixCls: 'ant-dropdown-button',
}; };
render() { render() {
const [{ type, overlay, trigger, align, children, className, onClick }, restProps] = splitObject(this.props, const [{ type, overlay, trigger, align, children, className, onClick, prefixCls }, restProps] =
['type', 'overlay', 'trigger', 'align', 'children', 'className', 'onClick']); splitObject(this.props,
['type', 'overlay', 'trigger', 'align', 'children', 'className', 'onClick', 'prefixCls']);
const cls = classNames({ const cls = classNames({
'ant-dropdown-button': true, [prefixCls]: true,
[className]: !!className, [className]: !!className,
}); });
return ( return (

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@dropdown-prefix-cls: ant-dropdown; @dropdown-prefix-cls: ~"@{ant-prefix}-dropdown";
.@{dropdown-prefix-cls} { .@{dropdown-prefix-cls} {
position: absolute; position: absolute;
@ -16,17 +16,17 @@
&-wrap { &-wrap {
position: relative; position: relative;
.ant-btn > .@{iconfont-css-prefix}-down { .@{ant-prefix}-btn > .@{iconfont-css-prefix}-down {
.iconfont-size-under-12px(10px); .iconfont-size-under-12px(10px);
} }
.anticon-down:before { .@{iconfont-css-prefix}-down:before {
transition: transform 0.2s ease; transition: transform 0.2s ease;
} }
} }
&-wrap-open { &-wrap-open {
.anticon-down:before { .@{iconfont-css-prefix}-down:before {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
@ -156,17 +156,17 @@
.@{dropdown-prefix-cls}-link { .@{dropdown-prefix-cls}-link {
font-size: 12px; font-size: 12px;
.anticon-down { .@{iconfont-css-prefix}-down {
.iconfont-size-under-12px(8px); .iconfont-size-under-12px(8px);
font-weight: bold; font-weight: bold;
} }
} }
.@{dropdown-prefix-cls}-button { .@{dropdown-prefix-cls}-button {
&.ant-btn-group > .ant-btn:last-child:not(:first-child) { &.@{ant-prefix}-btn-group > .@{ant-prefix}-btn:last-child:not(:first-child) {
padding-right: 7px; padding-right: 7px;
} }
.anticon-down { .@{iconfont-css-prefix}-down {
.iconfont-size-under-12px(10px); .iconfont-size-under-12px(10px);
} }
} }

View File

@ -5,7 +5,7 @@
@import "../../layout/style/mixin"; @import "../../layout/style/mixin";
@import "./mixin"; @import "./mixin";
@form-prefix-cls: ant-form; @form-prefix-cls: ~"@{ant-prefix}-form";
.reset-form(); .reset-form();
@ -38,10 +38,10 @@ input[type="checkbox"] {
} }
// These classes are used directly on <label>s // These classes are used directly on <label>s
.ant-radio-inline, .@{ant-prefix}-radio-inline,
.ant-radio-vertical, .@{ant-prefix}-radio-vertical,
.ant-checkbox-inline, .@{ant-prefix}-checkbox-inline,
.ant-checkbox-vertical { .@{ant-prefix}-checkbox-vertical {
&.disabled, &.disabled,
fieldset[disabled] & { fieldset[disabled] & {
cursor: @cursor-disabled; cursor: @cursor-disabled;
@ -49,8 +49,8 @@ input[type="checkbox"] {
} }
// These classes are used on elements with <label> descendants // These classes are used on elements with <label> descendants
.ant-radio, .@{ant-prefix}-radio,
.ant-checkbox { .@{ant-prefix}-checkbox {
&.disabled, &.disabled,
fieldset[disabled] & { fieldset[disabled] & {
label { label {
@ -100,7 +100,7 @@ input[type="checkbox"] {
} }
} }
.ant-switch { .@{ant-prefix}-switch {
margin: 4px 0; margin: 4px 0;
} }
@ -132,17 +132,17 @@ input[type="checkbox"] {
// 表单下的输入框尺寸唯一: 大尺寸 // 表单下的输入框尺寸唯一: 大尺寸
form { form {
.has-feedback { .has-feedback {
.ant-input { .@{ant-prefix}-input {
padding-right: 24px; padding-right: 24px;
} }
} }
textarea.ant-input { textarea.@{ant-prefix}-input {
height: auto; height: auto;
} }
// input[type=file] // input[type=file]
.ant-upload { .@{ant-prefix}-upload {
background: transparent; background: transparent;
} }
@ -153,8 +153,8 @@ form {
} }
// Radios and checkboxes on same line // Radios and checkboxes on same line
.ant-radio-inline, .@{ant-prefix}-radio-inline,
.ant-checkbox-inline { .@{ant-prefix}-checkbox-inline {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
font-weight: normal; font-weight: normal;
@ -166,30 +166,30 @@ form {
} }
} }
.ant-checkbox-vertical, .@{ant-prefix}-checkbox-vertical,
.ant-radio-vertical { .@{ant-prefix}-radio-vertical {
display: block; display: block;
} }
.ant-checkbox-vertical + .ant-checkbox-vertical, .@{ant-prefix}-checkbox-vertical + .@{ant-prefix}-checkbox-vertical,
.ant-radio-vertical + .ant-radio-vertical { .@{ant-prefix}-radio-vertical + .@{ant-prefix}-radio-vertical {
margin-left: 0; margin-left: 0;
} }
.ant-input-number { .@{ant-prefix}-input-number {
margin-top: -1px; margin-top: -1px;
margin-right: 8px; margin-right: 8px;
} }
.ant-select, .@{ant-prefix}-select,
.ant-cascader-picker { .@{ant-prefix}-cascader-picker {
width: 100%; width: 100%;
} }
} }
// Input combined with select // Input combined with select
.ant-input-group-wrap { .@{ant-prefix}-input-group-wrap {
.ant-select-selection { .@{ant-prefix}-select-selection {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-top-left-radius: 0; border-top-left-radius: 0;
&:hover { &:hover {
@ -197,18 +197,18 @@ form {
} }
} }
.ant-select-selection--single { .@{ant-prefix}-select-selection--single {
margin-left: -1px; margin-left: -1px;
height: @input-height-lg; height: @input-height-lg;
background-color: #eee; background-color: #eee;
.ant-select-selection__rendered { .@{ant-prefix}-select-selection__rendered {
padding-left: 8px; padding-left: 8px;
padding-right: 25px; padding-right: 25px;
line-height: 30px; line-height: 30px;
} }
} }
.ant-select-open .ant-select-selection { .@{ant-prefix}-select-open .@{ant-prefix}-select-selection {
border-color: @border-color-base; border-color: @border-color-base;
box-shadow: none; box-shadow: none;
} }
@ -221,8 +221,8 @@ form {
.make-row; .make-row;
} }
.ant-radio-inline, .@{ant-prefix}-radio-inline,
.ant-checkbox-inline { .@{ant-prefix}-checkbox-inline {
vertical-align: baseline; vertical-align: baseline;
} }
} }
@ -317,7 +317,7 @@ form {
} }
.has-success { .has-success {
.ant-input { .@{ant-prefix}-input {
border-color: @input-border-color; border-color: @input-border-color;
box-shadow: none; box-shadow: none;
} }
@ -337,7 +337,7 @@ form {
} }
//select //select
.ant-select { .@{ant-prefix}-select {
&-selection { &-selection {
border-color: @warning-color; border-color: @warning-color;
.active(@warning-color); .active(@warning-color);
@ -348,17 +348,17 @@ form {
} }
//datepicker //datepicker
.ant-calendar-picker-icon:after { .@{ant-prefix}-calendar-picker-icon:after {
color: @warning-color; color: @warning-color;
} }
//timepicker //timepicker
.ant-time-picker-icon:after { .@{ant-prefix}-time-picker-icon:after {
color: @warning-color; color: @warning-color;
} }
//input-number //input-number
.ant-input-number { .@{ant-prefix}-input-number {
border-color: @warning-color; border-color: @warning-color;
.active(@warning-color); .active(@warning-color);
&:not([disabled]):hover { &:not([disabled]):hover {
@ -376,7 +376,7 @@ form {
} }
//select //select
.ant-select { .@{ant-prefix}-select {
&-selection { &-selection {
border-color: @error-color; border-color: @error-color;
.active(@error-color); .active(@error-color);
@ -388,26 +388,26 @@ form {
} }
//datepicker //datepicker
.ant-calendar-picker-icon:after { .@{ant-prefix}-calendar-picker-icon:after {
color: @error-color; color: @error-color;
} }
//timepicker //timepicker
.ant-time-picker-picker-icon:after { .@{ant-prefix}-time-picker-picker-icon:after {
color: @error-color; color: @error-color;
} }
//input-number //input-number
.ant-input-number { .@{ant-prefix}-input-number {
border-color: @error-color; border-color: @error-color;
.active(@error-color); .active(@error-color);
&:not([disabled]):hover { &:not([disabled]):hover {
border-color: @error-color; border-color: @error-color;
} }
} }
.ant-mention-wrapper, .@{ant-prefix}-mention-wrapper,
.ant-mention-wrapper.active { .@{ant-prefix}-mention-wrapper.active {
.ant-mention-editor { .@{ant-prefix}-mention-editor {
border-color: @error-color; border-color: @error-color;
.active(@error-color); .active(@error-color);
&:not([disabled]):hover, &:not([disabled]):hover,
@ -428,13 +428,13 @@ form {
} }
} }
.ant-advanced-search-form { .@{ant-prefix}-advanced-search-form {
.@{form-prefix-cls}-item { .@{form-prefix-cls}-item {
margin-bottom: 16px; margin-bottom: 16px;
} }
.ant-input, .@{ant-prefix}-input,
.ant-input-group .ant-input, .@{ant-prefix}-input-group .@{ant-prefix}-input,
.ant-input-group .ant-input-group-addon { .@{ant-prefix}-input-group .@{ant-prefix}-input-group-addon {
height: 28px; height: 28px;
} }
} }

View File

@ -1,12 +1,12 @@
@import "../../input/style/mixin"; @import "../../input/style/mixin";
.form-control-validation(@text-color: @input-color; @border-color: @input-border-color; @background-color: @input-bg) { .form-control-validation(@text-color: @input-color; @border-color: @input-border-color; @background-color: @input-bg) {
.ant-form-explain, .@{ant-prefix}-form-explain,
.ant-form-split { .@{ant-prefix}-form-split {
color: @text-color; color: @text-color;
} }
// 输入框的不同校验状态 // 输入框的不同校验状态
.ant-input { .@{ant-prefix}-input {
&, &,
&:hover, &:hover,
&:focus { &:focus {
@ -19,11 +19,11 @@
} }
} }
.ant-calendar-picker-open .ant-calendar-picker-input { .@{ant-prefix}-calendar-picker-open .@{ant-prefix}-calendar-picker-input {
.active(@border-color); .active(@border-color);
} }
.ant-input-group-addon { .@{ant-prefix}-input-group-addon {
color: @text-color; color: @text-color;
border-color: @border-color; border-color: @border-color;
background-color: @background-color; background-color: @background-color;

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "../../input/style/mixin"; @import "../../input/style/mixin";
@input-number-prefix-cls: ant-input-number; @input-number-prefix-cls: ~"@{ant-prefix}-input-number";
.handler-disabled() { .handler-disabled() {
opacity: 0.72; opacity: 0.72;

View File

@ -6,13 +6,14 @@ export interface GroupProps {
size?: 'large' | 'small' | 'default'; size?: 'large' | 'small' | 'default';
children?: any; children?: any;
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string;
} }
const Group: React.StatelessComponent<GroupProps> = (props) => { const Group: React.StatelessComponent<GroupProps> = (props) => {
const className = classNames({ const className = classNames({
'ant-input-group': true, [props.prefixCls]: true,
'ant-input-group-lg': props.size === 'large', [`${props.prefixCls}-lg`]: props.size === 'large',
'ant-input-group-sm': props.size === 'small', [`${props.prefixCls}-sm`]: props.size === 'small',
[props.className]: !!props.className, [props.className]: !!props.className,
}); });
return ( return (
@ -26,4 +27,8 @@ Group.propTypes = {
children: React.PropTypes.any, children: React.PropTypes.any,
}; };
Group.defaultProps = {
prefixCls: 'ant-input-group',
};
export default Group; export default Group;

View File

@ -4,11 +4,11 @@
@import "./search-input"; @import "./search-input";
// Input styles // Input styles
.ant-input { .@{ant-prefix}-input {
.input; .input;
} }
//== Style for input-group: input with label, with button or dropdown... //== Style for input-group: input with label, with button or dropdown...
.ant-input-group { .@{ant-prefix}-input-group {
.input-group(~"ant-input"); .input-group(~"@{ant-prefix}-input");
} }

View File

@ -160,10 +160,10 @@
border-radius: @border-radius-base; border-radius: @border-radius-base;
// Reset Select's style in addon // Reset Select's style in addon
.ant-select { .@{ant-prefix}-select {
margin: -(@input-padding-vertical-base + 1) (-@input-padding-horizontal); // lesshint spaceAroundOperator: false margin: -(@input-padding-vertical-base + 1) (-@input-padding-horizontal); // lesshint spaceAroundOperator: false
.ant-select-selection { .@{ant-prefix}-select-selection {
background-color: inherit; background-color: inherit;
border: 0; border: 0;
margin: -1px; margin: -1px;
@ -172,7 +172,7 @@
&-open, &-open,
&-focused { &-focused {
.ant-select-selection { .@{ant-prefix}-select-selection {
border-color: tint(@primary-color, 20%); border-color: tint(@primary-color, 20%);
} }
} }
@ -187,7 +187,7 @@
border-top-right-radius: 0; border-top-right-radius: 0;
// Reset Select's style in addon // Reset Select's style in addon
.ant-select .ant-select-selection { .@{ant-prefix}-select .@{ant-prefix}-select-selection {
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
} }
@ -206,7 +206,7 @@
border-top-left-radius: 0; border-top-left-radius: 0;
// Reset Select's style in addon // Reset Select's style in addon
.ant-select .ant-select-selection { .@{ant-prefix}-select .@{ant-prefix}-select-selection {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-top-left-radius: 0; border-top-left-radius: 0;
} }

View File

@ -3,21 +3,21 @@
@import "../../button/style/mixin"; @import "../../button/style/mixin";
@import "./mixin"; @import "./mixin";
.ant-search-input-wrapper { .@{ant-prefix}-search-input-wrapper {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
} }
.ant-search-input { .@{ant-prefix}-search-input {
&.ant-input-group .ant-input:first-child, &.@{ant-prefix}-input-group .@{ant-prefix}-input:first-child,
&.ant-input-group .ant-select:first-child { &.@{ant-prefix}-input-group .@{ant-prefix}-select:first-child {
border-radius: @border-radius-base; border-radius: @border-radius-base;
position: absolute; position: absolute;
top: -1px; top: -1px;
width: 100%; width: 100%;
} }
.ant-search-btn { .@{ant-prefix}-search-btn {
.btn-default; .btn-default;
border-radius: 0 @border-radius-base - 1 @border-radius-base - 1 0; border-radius: 0 @border-radius-base - 1 @border-radius-base - 1 0;
left: -1px; left: -1px;
@ -34,12 +34,12 @@
padding-bottom: 6px; padding-bottom: 6px;
} }
} }
&&-focus .ant-search-btn-noempty, &&-focus .@{ant-prefix}-search-btn-noempty,
&:hover .ant-search-btn-noempty { &:hover .@{ant-prefix}-search-btn-noempty {
.btn-primary; .btn-primary;
} }
.ant-select-combobox { .@{ant-prefix}-select-combobox {
.ant-select-selection__rendered { .@{ant-prefix}-select-selection__rendered {
right: 29px; right: 29px;
} }
} }

View File

@ -26,11 +26,12 @@ export interface ColProps {
sm?: ColSize; sm?: ColSize;
md?: ColSize; md?: ColSize;
lg?: ColSize; lg?: ColSize;
prefixCls?: string;
} }
const Col: React.StatelessComponent<ColProps> = (props) => { const Col: React.StatelessComponent<ColProps> = (props) => {
const [{ span, order, offset, push, pull, className, children }, others] = splitObject(props, const [{ span, order, offset, push, pull, className, children, prefixCls = 'ant-col' }, others] = splitObject(props,
['span', 'order', 'offset', 'push', 'pull', 'className', 'children']); ['span', 'order', 'offset', 'push', 'pull', 'className', 'children', 'prefixCls']);
let sizeClassObj = {}; let sizeClassObj = {};
['xs', 'sm', 'md', 'lg'].forEach(size => { ['xs', 'sm', 'md', 'lg'].forEach(size => {
let sizeProps: ColSize = {}; let sizeProps: ColSize = {};
@ -43,19 +44,19 @@ const Col: React.StatelessComponent<ColProps> = (props) => {
delete others[size]; delete others[size];
sizeClassObj = assign({}, sizeClassObj, { sizeClassObj = assign({}, sizeClassObj, {
[`ant-col-${size}-${sizeProps.span}`]: sizeProps.span !== undefined, [`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
[`ant-col-${size}-order-${sizeProps.order}`]: sizeProps.order, [`${prefixCls}-${size}-order-${sizeProps.order}`]: sizeProps.order,
[`ant-col-${size}-offset-${sizeProps.offset}`]: sizeProps.offset, [`${prefixCls}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset,
[`ant-col-${size}-push-${sizeProps.push}`]: sizeProps.push, [`${prefixCls}-${size}-push-${sizeProps.push}`]: sizeProps.push,
[`ant-col-${size}-pull-${sizeProps.pull}`]: sizeProps.pull, [`${prefixCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull,
}); });
}); });
const classes = classNames(assign({}, { const classes = classNames(assign({}, {
[`ant-col-${span}`]: span !== undefined, [`${prefixCls}-${span}`]: span !== undefined,
[`ant-col-order-${order}`]: order, [`${prefixCls}-order-${order}`]: order,
[`ant-col-offset-${offset}`]: offset, [`${prefixCls}-offset-${offset}`]: offset,
[`ant-col-push-${push}`]: push, [`${prefixCls}-push-${push}`]: push,
[`ant-col-pull-${pull}`]: pull, [`${prefixCls}-pull-${pull}`]: pull,
[className]: !!className, [className]: !!className,
}, sizeClassObj)); }, sizeClassObj));

View File

@ -11,11 +11,13 @@ export interface RowProps {
align?: 'top' | 'middle' | 'bottom'; align?: 'top' | 'middle' | 'bottom';
justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between'; justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between';
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string;
} }
export default class Row extends React.Component<RowProps, any> { export default class Row extends React.Component<RowProps, any> {
static defaultProps = { static defaultProps = {
gutter: 0, gutter: 0,
prefixCls: 'ant-row',
}; };
static propTypes = { static propTypes = {
type: React.PropTypes.string, type: React.PropTypes.string,
@ -24,15 +26,16 @@ export default class Row extends React.Component<RowProps, any> {
className: React.PropTypes.string, className: React.PropTypes.string,
children: React.PropTypes.node, children: React.PropTypes.node,
gutter: React.PropTypes.number, gutter: React.PropTypes.number,
prefixCls: React.PropTypes.string,
}; };
render() { render() {
const [{ type, justify, align, className, gutter, style, children }, others] = splitObject(this.props, const [{ type, justify, align, className, gutter, style, children, prefixCls }, others] = splitObject(this.props,
['type', 'justify', 'align', 'className', 'gutter', 'style', 'children']); ['type', 'justify', 'align', 'className', 'gutter', 'style', 'children', 'prefixCls']);
const classes = classNames({ const classes = classNames({
'ant-row': !type, [prefixCls]: !type,
[`ant-row-${type}`]: type, [`${prefixCls}-${type}`]: type,
[`ant-row-${type}-${justify}`]: justify, [`${prefixCls}-${type}-${justify}`]: justify,
[`ant-row-${type}-${align}`]: align, [`${prefixCls}-${type}-${align}`]: align,
[className]: className, [className]: className,
}); });
const rowStyle = gutter > 0 ? assign({}, { const rowStyle = gutter > 0 ? assign({}, {

View File

@ -3,12 +3,12 @@
@import "./mixin"; @import "./mixin";
// Grid system // Grid system
.ant-row { .@{ant-prefix}-row {
.make-row(); .make-row();
display: block; display: block;
} }
.ant-row-flex { .@{ant-prefix}-row-flex {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
@ -20,46 +20,46 @@
} }
// x轴原点 // x轴原点
.ant-row-flex-start { .@{ant-prefix}-row-flex-start {
justify-content: flex-start; justify-content: flex-start;
} }
// x轴居中 // x轴居中
.ant-row-flex-center { .@{ant-prefix}-row-flex-center {
justify-content: center; justify-content: center;
} }
// x轴反方向 // x轴反方向
.ant-row-flex-end { .@{ant-prefix}-row-flex-end {
justify-content: flex-end; justify-content: flex-end;
} }
// x轴平分 // x轴平分
.ant-row-flex-space-between { .@{ant-prefix}-row-flex-space-between {
justify-content: space-between; justify-content: space-between;
} }
// x轴有间隔地平分 // x轴有间隔地平分
.ant-row-flex-space-around { .@{ant-prefix}-row-flex-space-around {
justify-content: space-around; justify-content: space-around;
} }
// 顶部对齐 // 顶部对齐
.ant-row-flex-top { .@{ant-prefix}-row-flex-top {
align-items: flex-start; align-items: flex-start;
} }
// 居中对齐 // 居中对齐
.ant-row-flex-middle { .@{ant-prefix}-row-flex-middle {
align-items: center; align-items: center;
} }
// 底部对齐 // 底部对齐
.ant-row-flex-bottom { .@{ant-prefix}-row-flex-bottom {
align-items: flex-end; align-items: flex-end;
} }
.ant-col { .@{ant-prefix}-col {
position: relative; position: relative;
display: block; display: block;
} }

View File

@ -12,11 +12,11 @@
.make-grid-columns() { .make-grid-columns() {
.col(@index) { .col(@index) {
@item: ~".ant-col-@{index}, .ant-col-xs-@{index}, .ant-col-sm-@{index}, .ant-col-md-@{index}, .ant-col-lg-@{index}"; @item: ~".@{ant-prefix}-col-@{index}, .@{ant-prefix}-col-xs-@{index}, .@{ant-prefix}-col-sm-@{index}, .@{ant-prefix}-col-md-@{index}, .@{ant-prefix}-col-lg-@{index}";
.col((@index + 1), @item); .col((@index + 1), @item);
} }
.col(@index, @list) when (@index =< @grid-columns) { .col(@index, @list) when (@index =< @grid-columns) {
@item: ~".ant-col-@{index}, .ant-col-xs-@{index}, .ant-col-sm-@{index}, .ant-col-md-@{index}, .ant-col-lg-@{index}"; @item: ~".@{ant-prefix}-col-@{index}, .@{ant-prefix}-col-xs-@{index}, .@{ant-prefix}-col-sm-@{index}, .@{ant-prefix}-col-md-@{index}, .@{ant-prefix}-col-lg-@{index}";
.col((@index + 1), ~"@{list}, @{item}"); .col((@index + 1), ~"@{list}, @{item}");
} }
.col(@index, @list) when (@index > @grid-columns) { .col(@index, @list) when (@index > @grid-columns) {
@ -33,11 +33,11 @@
.float-grid-columns(@class) { .float-grid-columns(@class) {
.col(@index) { // initial .col(@index) { // initial
@item: ~".ant-col@{class}-@{index}"; @item: ~".@{ant-prefix}-col@{class}-@{index}";
.col((@index + 1), @item); .col((@index + 1), @item);
} }
.col(@index, @list) when (@index =< @grid-columns) { // general .col(@index, @list) when (@index =< @grid-columns) { // general
@item: ~".ant-col@{class}-@{index}"; @item: ~".@{ant-prefix}-col@{class}-@{index}";
.col((@index + 1), ~"@{list}, @{item}"); .col((@index + 1), ~"@{list}, @{item}");
} }
.col(@index, @list) when (@index > @grid-columns) { // terminal .col(@index, @list) when (@index > @grid-columns) { // terminal
@ -51,33 +51,33 @@
// lesshint false // lesshint false
.loop-grid-columns(@index, @class) when (@index > 0) { .loop-grid-columns(@index, @class) when (@index > 0) {
.ant-col@{class}-@{index} { .@{ant-prefix}-col@{class}-@{index} {
display: block; display: block;
width: percentage((@index / @grid-columns)); width: percentage((@index / @grid-columns));
} }
.ant-col@{class}-push-@{index} { .@{ant-prefix}-col@{class}-push-@{index} {
left: percentage((@index / @grid-columns)); left: percentage((@index / @grid-columns));
} }
.ant-col@{class}-pull-@{index} { .@{ant-prefix}-col@{class}-pull-@{index} {
right: percentage((@index / @grid-columns)); right: percentage((@index / @grid-columns));
} }
.ant-col@{class}-offset-@{index} { .@{ant-prefix}-col@{class}-offset-@{index} {
margin-left: percentage((@index / @grid-columns)); margin-left: percentage((@index / @grid-columns));
} }
.ant-col@{class}-order-@{index} { .@{ant-prefix}-col@{class}-order-@{index} {
order: @index; order: @index;
} }
.loop-grid-columns((@index - 1), @class); .loop-grid-columns((@index - 1), @class);
} }
.loop-grid-columns(@index, @class) when (@index = 0) { .loop-grid-columns(@index, @class) when (@index = 0) {
.ant-col@{class}-@{index} { .@{ant-prefix}-col@{class}-@{index} {
display: none; display: none;
} }
.ant-col-push-@{index} { .@{ant-prefix}-col-push-@{index} {
left: auto; left: auto;
} }
.ant-col-pull-@{index} { .@{ant-prefix}-col-pull-@{index} {
right: auto; right: auto;
} }
} }

View File

@ -2,20 +2,20 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import '../../input/style/mixin.less'; @import '../../input/style/mixin.less';
.ant-mention-wrapper { .@{ant-prefix}-mention-wrapper {
position: relative; position: relative;
display: inline-block; display: inline-block;
width: 100%; width: 100%;
vertical-align: middle; vertical-align: middle;
&.active .ant-mention-editor { &.active .@{ant-prefix}-mention-editor {
.active; .active;
} }
.ant-mention-editor { .@{ant-prefix}-mention-editor {
.input; .input;
padding: 0; padding: 0;
display: block; display: block;
} }
.ant-mention-editor-wrapper { .@{ant-prefix}-mention-editor-wrapper {
overflow-y: auto; overflow-y: auto;
height: auto; height: auto;
} }
@ -25,7 +25,7 @@
padding: 4px 7px; padding: 4px 7px;
} }
.ant-mention-dropdown { .@{ant-prefix}-mention-dropdown {
margin-top: 1.5em; margin-top: 1.5em;
max-height: 250px; max-height: 250px;
min-width: 120px; min-width: 120px;
@ -42,10 +42,10 @@
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
font-size: @font-size-base; font-size: @font-size-base;
&-notfound.ant-mention-dropdown-item { &-notfound.@{ant-prefix}-mention-dropdown-item {
color: #ccc; color: #ccc;
.anticon-loading { .@{iconfont-css-prefix}-loading {
color: @primary-color; color: @primary-color;
} }
} }

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@menu-prefix-cls: ant-menu; @menu-prefix-cls: ~"@{ant-prefix}-menu";
// default theme // default theme
.@{menu-prefix-cls} { .@{menu-prefix-cls} {
@ -164,7 +164,7 @@
} }
} }
.anticon { .@{iconfont-css-prefix} {
min-width: 14px; min-width: 14px;
margin-right: 8px; margin-right: 8px;
} }

View File

@ -1,6 +1,6 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@message-prefix-cls: ant-message; @message-prefix-cls: ~"@{ant-prefix}-message";
.@{message-prefix-cls} { .@{message-prefix-cls} {
font-size: 12px; font-size: 12px;
@ -28,24 +28,24 @@
display: block; display: block;
} }
&-success .anticon { &-success .@{iconfont-css-prefix} {
color: @success-color; color: @success-color;
} }
&-error .anticon { &-error .@{iconfont-css-prefix} {
color: @error-color; color: @error-color;
} }
&-warning .anticon { &-warning .@{iconfont-css-prefix} {
color: @warning-color; color: @warning-color;
} }
&-info .anticon, &-info .@{iconfont-css-prefix},
&-loading .anticon { &-loading .@{iconfont-css-prefix} {
color: @primary-color; color: @primary-color;
} }
.anticon { .@{iconfont-css-prefix} {
margin-right: 8px; margin-right: 8px;
font-size: 14px; font-size: 14px;
top: 1px; top: 1px;

View File

@ -58,6 +58,7 @@ class ActionButton extends React.Component<ActionButtonProps, any> {
export default function confirm(config) { export default function confirm(config) {
const props = assign({ iconType: 'question-circle' }, config); const props = assign({ iconType: 'question-circle' }, config);
const prefixCls = props.prefixCls || 'ant-confirm';
let div = document.createElement('div'); let div = document.createElement('div');
document.body.appendChild(div); document.body.appendChild(div);
@ -83,17 +84,17 @@ export default function confirm(config) {
} }
let body = ( let body = (
<div className="ant-confirm-body"> <div className={`${prefixCls}-body`}>
<Icon type={props.iconType} /> <Icon type={props.iconType} />
<span className="ant-confirm-title">{props.title}</span> <span className={`${prefixCls}-title`}>{props.title}</span>
<div className="ant-confirm-content">{props.content}</div> <div className={`${prefixCls}-content`}>{props.content}</div>
</div> </div>
); );
let footer = null; let footer = null;
if (props.okCancel) { if (props.okCancel) {
footer = ( footer = (
<div className="ant-confirm-btns"> <div className={`${prefixCls}-btns`}>
<ActionButton type="ghost" actionFn={props.onCancel} closeModal={close}> <ActionButton type="ghost" actionFn={props.onCancel} closeModal={close}>
{props.cancelText} {props.cancelText}
</ActionButton> </ActionButton>
@ -104,7 +105,7 @@ export default function confirm(config) {
); );
} else { } else {
footer = ( footer = (
<div className="ant-confirm-btns"> <div className={`${prefixCls}-btns`}>
<ActionButton type="primary" actionFn={props.onOk} closeModal={close}> <ActionButton type="primary" actionFn={props.onOk} closeModal={close}>
{props.okText} {props.okText}
</ActionButton> </ActionButton>
@ -113,8 +114,8 @@ export default function confirm(config) {
} }
const classString = classNames({ const classString = classNames({
'ant-confirm': true, [prefixCls]: true,
[`ant-confirm-${props.type}`]: true, [`${prefixCls}-${props.type}`]: true,
[props.className]: !!props.className, [props.className]: !!props.className,
}); });

View File

@ -1,11 +1,11 @@
@confirm-prefix-cls: ant-confirm; @confirm-prefix-cls: ~"@{ant-prefix}-confirm";
.@{confirm-prefix-cls} { .@{confirm-prefix-cls} {
.ant-modal-header { .@{ant-prefix}-modal-header {
display: none; display: none;
} }
.ant-modal-body { .@{ant-prefix}-modal-body {
padding: 30px 40px; padding: 30px 40px;
} }
@ -23,7 +23,7 @@
margin-top: 8px; margin-top: 8px;
} }
> .anticon { > .@{iconfont-css-prefix} {
font-size: 24px; font-size: 24px;
margin-right: 10px; margin-right: 10px;
padding: 0 1px; padding: 0 1px;
@ -42,20 +42,20 @@
} }
} }
&-error &-body > .anticon { &-error &-body > .@{iconfont-css-prefix} {
color: @error-color; color: @error-color;
} }
&-warning &-body > .anticon, &-warning &-body > .@{iconfont-css-prefix},
&-confirm &-body > .anticon { &-confirm &-body > .@{iconfont-css-prefix} {
color: @warning-color; color: @warning-color;
} }
&-info &-body > .anticon { &-info &-body > .@{iconfont-css-prefix} {
color: @primary-color; color: @primary-color;
} }
&-success &-body > .anticon { &-success &-body > .@{iconfont-css-prefix} {
color: @success-color; color: @success-color;
} }
} }

View File

@ -1,4 +1,4 @@
@dialog-prefix-cls: ant-modal; @dialog-prefix-cls: ~"@{ant-prefix}-modal";
.@{dialog-prefix-cls} { .@{dialog-prefix-cls} {
position: relative; position: relative;

View File

@ -16,12 +16,12 @@ export interface ArgsProps {
icon?: React.ReactNode; icon?: React.ReactNode;
} }
function getNotificationInstance() { function getNotificationInstance(prefixCls) {
if (notificationInstance) { if (notificationInstance) {
return notificationInstance; return notificationInstance;
} }
notificationInstance = (Notification as any).newInstance({ notificationInstance = (Notification as any).newInstance({
prefixCls: 'ant-notification', prefixCls: prefixCls,
style: { style: {
top: defaultTop, top: defaultTop,
right: 0, right: 0,
@ -31,7 +31,8 @@ function getNotificationInstance() {
} }
function notice(args) { function notice(args) {
const prefixCls = args.prefixCls || 'ant-notification-notice'; const outerPrefixCls = args.prefixCls || 'ant-notification';
const prefixCls = `${outerPrefixCls}-notice`;
let duration; let duration;
if (args.duration === undefined) { if (args.duration === undefined) {
@ -69,7 +70,7 @@ function notice(args) {
iconNode = <Icon className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`} type={iconType} />; iconNode = <Icon className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`} type={iconType} />;
} }
getNotificationInstance().notice({ getNotificationInstance(outerPrefixCls).notice({
content: ( content: (
<div className={`${prefixCls}-content ${iconNode ? `${prefixCls}-with-icon` : ''}`}> <div className={`${prefixCls}-content ${iconNode ? `${prefixCls}-with-icon` : ''}`}>
{iconNode} {iconNode}

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@notification-prefix-cls: ant-notification; @notification-prefix-cls: ~"@{ant-prefix}-notification";
@notification-width: 335px; @notification-width: 335px;
@notification-padding: 16px; @notification-padding: 16px;
@notification-margin-bottom: 10px; @notification-margin-bottom: 10px;

View File

@ -34,6 +34,8 @@ export interface PaginationProps {
style?: React.CSSProperties; style?: React.CSSProperties;
className?: string; className?: string;
locale?: Object; locale?: Object;
prefixCls?: string;
selectPrefixCls?: string;
} }
export interface PaginationContext { export interface PaginationContext {
@ -47,6 +49,7 @@ export default class Pagination extends React.Component<PaginationProps, any> {
locale: zhCN, locale: zhCN,
className: '', className: '',
prefixCls: 'ant-pagination', prefixCls: 'ant-pagination',
selectPrefixCls: 'ant-select',
}; };
static contextTypes = { static contextTypes = {
@ -73,7 +76,7 @@ export default class Pagination extends React.Component<PaginationProps, any> {
return ( return (
<RcPagination selectComponentClass={selectComponentClass} <RcPagination selectComponentClass={selectComponentClass}
selectPrefixCls="ant-select" selectPrefixCls={this.props.selectPrefixCls}
{...this.props} {...this.props}
locale={locale} locale={locale}
className={className} className={className}

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "../../input/style/mixin"; @import "../../input/style/mixin";
@pagination-prefix-cls: ant-pagination; @pagination-prefix-cls: ~"@{ant-prefix}-pagination";
.@{pagination-prefix-cls} { .@{pagination-prefix-cls} {
font-size: @font-size-base; font-size: @font-size-base;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@popover-prefix-cls: ant-popover; @popover-prefix-cls: ~"@{ant-prefix}-popover";
//** Popover body background color //** Popover body background color
@popover-bg: #fff; @popover-bg: #fff;
@ -96,7 +96,7 @@
padding: 8px 0 16px; padding: 8px 0 16px;
font-size: 12px; font-size: 12px;
color: @text-color; color: @text-color;
> .anticon { > .@{iconfont-css-prefix} {
color: @warning-color; color: @warning-color;
line-height: 17px; line-height: 17px;
position: absolute; position: absolute;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@progress-prefix-cls: ant-progress; @progress-prefix-cls: ~"@{ant-prefix}-progress";
.@{progress-prefix-cls} { .@{progress-prefix-cls} {
display: inline-block; display: inline-block;
@ -46,7 +46,7 @@
vertical-align: middle; vertical-align: middle;
display: inline-block; display: inline-block;
font-family: tahoma; font-family: tahoma;
.anticon { .@{iconfont-css-prefix} {
font-size: 12px; font-size: 12px;
} }
} }
@ -62,7 +62,7 @@
bottom: 0; bottom: 0;
background: #fff; background: #fff;
border-radius: 10px; border-radius: 10px;
animation: ant-progress-active 2s @ease-out-quint infinite; animation: ~"@{ant-prefix}-progress-active" 2s @ease-out-quint infinite;
} }
} }
@ -102,7 +102,7 @@
font-family: tahoma; font-family: tahoma;
margin: 0; margin: 0;
.anticon { .@{iconfont-css-prefix} {
font-size: 14 / 12em; font-size: 14 / 12em;
} }
} }
@ -119,7 +119,7 @@
} }
} }
@keyframes ant-progress-active { @keyframes ~"@{ant-prefix}-progress-active" {
0% { 0% {
opacity: .3; opacity: .3;
width: 0; width: 0;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@radio-prefix-cls: ant-radio; @radio-prefix-cls: ~"@{ant-prefix}-radio";
@radio-group-prefix-cls: ~"@{radio-prefix-cls}-group"; @radio-group-prefix-cls: ~"@{radio-prefix-cls}-group";
@radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner"; @radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner";
@radio-duration: .2s; @radio-duration: .2s;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@rate-prefix-cls: ant-rate; @rate-prefix-cls: ~"@{ant-prefix}-rate";
@rate-star-color: #f5a623; @rate-star-color: #f5a623;
.@{rate-prefix-cls} { .@{rate-prefix-cls} {

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "../../input/style/mixin"; @import "../../input/style/mixin";
@select-prefix-cls: ant-select; @select-prefix-cls: ~"@{ant-prefix}-select";
.selection__clear() { .selection__clear() {
display: inline-block; display: inline-block;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@slider-prefix-cls: ant-slider; @slider-prefix-cls: ~"@{ant-prefix}-slider";
// slider color // slider color
@slider-disabled-color: #ccc; @slider-disabled-color: #ccc;
// tooltip // tooltip

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@spin-prefix-cls: ant-spin; @spin-prefix-cls: ~"@{ant-prefix}-spin";
@spin-dot-default: #999; @spin-dot-default: #999;
@spin-dot-size-sm: 12px; @spin-dot-size-sm: 12px;
@spin-dot-size: 20px; @spin-dot-size: 20px;
@ -123,7 +123,7 @@
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
/* IE10+ */ /* IE10+ */
.ant-spin-nested-loading > .ant-spin-container { .@{ant-prefix}-spin-nested-loading > .@{ant-prefix}-spin-container {
background: #fff; background: #fff;
opacity: 0.5; opacity: 0.5;
} }

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@steps-prefix-cls: ant-steps; @steps-prefix-cls: ~"@{ant-prefix}-steps";
@process-icon-color: @primary-color; @process-icon-color: @primary-color;
@process-title-color: #666; @process-title-color: #666;
@process-description-color: @process-title-color; @process-description-color: @process-title-color;
@ -161,7 +161,7 @@
color: @primary-color; color: @primary-color;
position: relative; position: relative;
&.anticon { &.@{iconfont-css-prefix} {
font-size: 12px; font-size: 12px;
&-cross, &-cross,
&-check { &-check {
@ -231,7 +231,7 @@
border-radius: 18px; border-radius: 18px;
font-size: 12px; font-size: 12px;
margin-right: 10px; margin-right: 10px;
> .@{steps-prefix-cls}-icon.anticon { > .@{steps-prefix-cls}-icon.@{iconfont-css-prefix} {
.iconfont-size-under-12px(9px); .iconfont-size-under-12px(9px);
top: 0; top: 0;
} }

View File

@ -102,7 +102,7 @@ a {
visibility: hidden; visibility: hidden;
} }
.ant-divider { .@{ant-prefix}-divider {
margin: 0 4px; margin: 0 4px;
color: #999; color: #999;
display: inline-block; display: inline-block;

View File

@ -1,3 +1,6 @@
// Prefix
@ant-prefix : ant;
// Color // Color
@primary-color : #2db7f5; @primary-color : #2db7f5;
@info-color : #2db7f5; @info-color : #2db7f5;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@switch-prefix-cls: ant-switch; @switch-prefix-cls: ~"@{ant-prefix}-switch";
@switch-duration: .3s; @switch-duration: .3s;
.@{switch-prefix-cls} { .@{switch-prefix-cls} {

View File

@ -63,6 +63,7 @@ export interface TableColumnConfig {
export interface TableProps { export interface TableProps {
prefixCls?: string; prefixCls?: string;
dropdownPrefixCls?: string;
rowSelection?: TableRowSelection; rowSelection?: TableRowSelection;
pagination?: any; // 等 Pagination 的 interface以便直接引用 pagination?: any; // 等 Pagination 的 interface以便直接引用
size?: 'default' | 'small'; size?: 'default' | 'small';
@ -107,11 +108,13 @@ export default class Table extends React.Component<TableProps, any> {
bordered: React.PropTypes.bool, bordered: React.PropTypes.bool,
onChange: React.PropTypes.func, onChange: React.PropTypes.func,
locale: React.PropTypes.object, locale: React.PropTypes.object,
dropdownPrefixCls: React.PropTypes.string,
}; };
static defaultProps = { static defaultProps = {
dataSource: [], dataSource: [],
prefixCls: 'ant-table', prefixCls: 'ant-table',
dropdownPrefixCls: 'ant-dropdown',
useFixedHeader: false, useFixedHeader: false,
rowSelection: null, rowSelection: null,
className: '', className: '',
@ -561,6 +564,7 @@ export default class Table extends React.Component<TableProps, any> {
} }
renderRowSelection() { renderRowSelection() {
const prefixCls = this.props.prefixCls;
const columns = this.props.columns.concat(); const columns = this.props.columns.concat();
if (this.props.rowSelection) { if (this.props.rowSelection) {
const data = this.getFlatCurrentPageData().filter((item) => { const data = this.getFlatCurrentPageData().filter((item) => {
@ -587,7 +591,7 @@ export default class Table extends React.Component<TableProps, any> {
selectionColumn = { selectionColumn = {
key: 'selection-column', key: 'selection-column',
render: this.renderSelectionRadio, render: this.renderSelectionRadio,
className: 'ant-table-selection-column', className: `${prefixCls}-selection-column`,
}; };
} else { } else {
const checkboxAllDisabled = data.every(item => this.getCheckboxPropsByItem(item).disabled); const checkboxAllDisabled = data.every(item => this.getCheckboxPropsByItem(item).disabled);
@ -601,7 +605,7 @@ export default class Table extends React.Component<TableProps, any> {
key: 'selection-column', key: 'selection-column',
title: checkboxAll, title: checkboxAll,
render: this.renderSelectionCheckBox, render: this.renderSelectionCheckBox,
className: 'ant-table-selection-column', className: `${prefixCls}-selection-column`,
}; };
} }
if (columns.some(column => column.fixed === 'left' || column.fixed === true)) { if (columns.some(column => column.fixed === 'left' || column.fixed === true)) {
@ -637,6 +641,7 @@ export default class Table extends React.Component<TableProps, any> {
} }
renderColumnsDropdown(columns) { renderColumnsDropdown(columns) {
const { prefixCls, dropdownPrefixCls } = this.props;
const { sortOrder } = this.state; const { sortOrder } = this.state;
const locale = this.getLocale(); const locale = this.getLocale();
return treeMap(columns, (originColumn, i) => { return treeMap(columns, (originColumn, i) => {
@ -652,6 +657,8 @@ export default class Table extends React.Component<TableProps, any> {
column={column} column={column}
selectedKeys={colFilters} selectedKeys={colFilters}
confirmFilter={this.handleFilter} confirmFilter={this.handleFilter}
prefixCls={`${prefixCls}-filter`}
dropdownPrefixCls={dropdownPrefixCls}
/> />
); );
} }
@ -660,20 +667,20 @@ export default class Table extends React.Component<TableProps, any> {
if (isSortColumn) { if (isSortColumn) {
column.className = column.className || ''; column.className = column.className || '';
if (sortOrder) { if (sortOrder) {
column.className += ' ant-table-column-sort'; column.className += ` ${prefixCls}-column-sort`;
} }
} }
const isAscend = isSortColumn && sortOrder === 'ascend'; const isAscend = isSortColumn && sortOrder === 'ascend';
const isDescend = isSortColumn && sortOrder === 'descend'; const isDescend = isSortColumn && sortOrder === 'descend';
sortButton = ( sortButton = (
<div className="ant-table-column-sorter"> <div className={`${prefixCls}-column-sorter`}>
<span className={`ant-table-column-sorter-up ${isAscend ? 'on' : 'off'}`} <span className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
title="↑" title="↑"
onClick={() => this.toggleSortOrder('ascend', column)} onClick={() => this.toggleSortOrder('ascend', column)}
> >
<Icon type="caret-up" /> <Icon type="caret-up" />
</span> </span>
<span className={`ant-table-column-sorter-down ${isDescend ? 'on' : 'off'}`} <span className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
title="↓" title="↓"
onClick={() => this.toggleSortOrder('descend', column)} onClick={() => this.toggleSortOrder('descend', column)}
> >
@ -821,17 +828,17 @@ export default class Table extends React.Component<TableProps, any> {
render() { render() {
const [{ const [{
style, className, style, className, prefixCls,
}, restProps] = splitObject(this.props, ['style', 'className']); }, restProps] = splitObject(this.props, ['style', 'className', 'prefixCls']);
const data = this.getCurrentPageData(); const data = this.getCurrentPageData();
let columns = this.renderRowSelection(); let columns = this.renderRowSelection();
const expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false; const expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false;
const locale = this.getLocale(); const locale = this.getLocale();
const classString = classNames({ const classString = classNames({
[`ant-table-${this.props.size}`]: true, [`${prefixCls}-${this.props.size}`]: true,
'ant-table-bordered': this.props.bordered, [`${prefixCls}-bordered`]: this.props.bordered,
'ant-table-empty': !data.length, [`${prefixCls}-empty`]: !data.length,
}); });
columns = this.renderColumnsDropdown(columns); columns = this.renderColumnsDropdown(columns);
@ -854,9 +861,9 @@ export default class Table extends React.Component<TableProps, any> {
// if there is no pagination or no data, // if there is no pagination or no data,
// the height of spin should decrease by half of pagination // the height of spin should decrease by half of pagination
const paginationPatchClass = (this.hasPagination() && data && data.length !== 0) const paginationPatchClass = (this.hasPagination() && data && data.length !== 0)
? 'ant-table-with-pagination' ? `${prefixCls}-with-pagination`
: 'ant-table-without-pagination'; : `${prefixCls}-without-pagination`;
const spinClassName = this.props.loading ? `${paginationPatchClass} ant-table-spin-holder` : ''; const spinClassName = this.props.loading ? `${paginationPatchClass} ${prefixCls}-spin-holder` : '';
table = <Spin className={spinClassName} spinning={this.props.loading}>{table}</Spin>; table = <Spin className={spinClassName} spinning={this.props.loading}>{table}</Spin>;
return ( return (
<div className={`${className} clearfix`} style={style}> <div className={`${className} clearfix`} style={style}>

View File

@ -8,9 +8,11 @@ import Radio from '../radio';
export interface FilterDropdownMenuWrapperProps { export interface FilterDropdownMenuWrapperProps {
onClick?: Function; onClick?: Function;
children?: any; children?: any;
prefixCls?: string;
} }
const FilterDropdownMenuWrapper: React.StatelessComponent<FilterDropdownMenuWrapperProps> = ({ onClick, children }) => ( const FilterDropdownMenuWrapper: React.StatelessComponent<FilterDropdownMenuWrapperProps> =
<div className="ant-table-filter-dropdown" onClick={onClick}>{children}</div> ({ onClick, children, prefixCls }) => (
<div className={`${prefixCls}-filter-dropdown`} onClick={onClick}>{children}</div>
); );
export interface FilterMenuProps { export interface FilterMenuProps {
@ -22,6 +24,8 @@ export interface FilterMenuProps {
filters?: string[] filters?: string[]
}; };
confirmFilter: (column: Object, selectedKeys: string[]) => any; confirmFilter: (column: Object, selectedKeys: string[]) => any;
prefixCls: string;
dropdownPrefixCls: string;
} }
export default class FilterMenu extends React.Component<FilterMenuProps, any> { export default class FilterMenu extends React.Component<FilterMenuProps, any> {
@ -100,7 +104,7 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
const containSelected = Object.keys(keyPathOfSelectedItem).some( const containSelected = Object.keys(keyPathOfSelectedItem).some(
key => keyPathOfSelectedItem[key].indexOf(item.value) >= 0 key => keyPathOfSelectedItem[key].indexOf(item.value) >= 0
); );
const subMenuCls = containSelected ? 'ant-dropdown-submenu-contain-selected' : ''; const subMenuCls = containSelected ? `${this.props.dropdownPrefixCls}-submenu-contain-selected` : '';
return ( return (
<SubMenu title={item.text} className={subMenuCls} key={item.value.toString()}> <SubMenu title={item.text} className={subMenuCls} key={item.value.toString()}>
{item.children.map(child => this.renderMenuItem(child))} {item.children.map(child => this.renderMenuItem(child))}
@ -127,31 +131,31 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
} }
render() { render() {
const { column, locale } = this.props; const { column, locale, prefixCls, dropdownPrefixCls } = this.props;
// default multiple selection in filter dropdown // default multiple selection in filter dropdown
const multiple = ('filterMultiple' in column) ? column.filterMultiple : true; const multiple = ('filterMultiple' in column) ? column.filterMultiple : true;
const menus = column.filterDropdown ? column.filterDropdown : ( const menus = column.filterDropdown ? column.filterDropdown : (
<FilterDropdownMenuWrapper> <FilterDropdownMenuWrapper prefixCls="">
<Menu <Menu
multiple={multiple} multiple={multiple}
onClick={this.handleMenuItemClick} onClick={this.handleMenuItemClick}
prefixCls="ant-dropdown-menu" prefixCls={`${dropdownPrefixCls}-menu`}
onSelect={this.setSelectedKeys} onSelect={this.setSelectedKeys}
onDeselect={this.setSelectedKeys} onDeselect={this.setSelectedKeys}
selectedKeys={this.state.selectedKeys} selectedKeys={this.state.selectedKeys}
> >
{this.renderMenus(column.filters)} {this.renderMenus(column.filters)}
</Menu> </Menu>
<div className="ant-table-filter-dropdown-btns"> <div className={`${prefixCls}-dropdown-btns`}>
<a <a
className="ant-table-filter-dropdown-link confirm" className={`${prefixCls}-dropdown-link confirm`}
onClick={this.handleConfirm} onClick={this.handleConfirm}
> >
{locale.filterConfirm} {locale.filterConfirm}
</a> </a>
<a <a
className="ant-table-filter-dropdown-link clear" className={`${prefixCls}-dropdown-link clear`}
onClick={this.handleClearFilters} onClick={this.handleClearFilters}
> >
{locale.filterReset} {locale.filterReset}
@ -161,7 +165,7 @@ export default class FilterMenu extends React.Component<FilterMenuProps, any> {
); );
const dropdownSelectedClass = (this.props.selectedKeys.length > 0) const dropdownSelectedClass = (this.props.selectedKeys.length > 0)
? 'ant-table-filter-selected' : ''; ? `${prefixCls}-selected` : '';
return ( return (
<Dropdown <Dropdown

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@table-prefix-cls: ant-table; @table-prefix-cls: ~"@{ant-prefix}-table";
@table-head-background-color: @background-color-base; @table-head-background-color: @background-color-base;
.@{table-prefix-cls} { .@{table-prefix-cls} {
@ -31,7 +31,7 @@
transition: background .3s ease; transition: background .3s ease;
text-align: left; text-align: left;
.anticon-filter { .@{iconfont-css-prefix}-filter {
margin-left: 4px; margin-left: 4px;
.iconfont-size-under-12px(10px); .iconfont-size-under-12px(10px);
cursor: pointer; cursor: pointer;
@ -42,7 +42,7 @@
} }
} }
.@{table-prefix-cls}-filter-selected.anticon-filter { .@{table-prefix-cls}-filter-selected.@{iconfont-css-prefix}-filter {
color: @primary-color; color: @primary-color;
} }
} }
@ -208,18 +208,18 @@
display: block; display: block;
width: 12px; width: 12px;
cursor: pointer; cursor: pointer;
&:hover .anticon { &:hover .@{iconfont-css-prefix} {
color: #666; color: #666;
} }
&.on { &.on {
.anticon-caret-up, .@{iconfont-css-prefix}-caret-up,
.anticon-caret-down { .@{iconfont-css-prefix}-caret-down {
color: @primary-color; color: @primary-color;
} }
} }
} }
.anticon-caret-up, .@{iconfont-css-prefix}-caret-up,
.anticon-caret-down { .@{iconfont-css-prefix}-caret-down {
.iconfont-size-under-12px(6px); .iconfont-size-under-12px(6px);
line-height: 6px; line-height: 6px;
height: 6px; height: 6px;
@ -287,7 +287,7 @@
z-index: 2; z-index: 2;
font-size: 12px; font-size: 12px;
color: #999; color: #999;
.anticon { .@{iconfont-css-prefix} {
margin-right: 4px; margin-right: 4px;
} }
} }
@ -305,7 +305,7 @@
border: 1px solid @border-color-base; border: 1px solid @border-color-base;
box-shadow: @box-shadow-base; box-shadow: @box-shadow-base;
.ant-dropdown-menu { .@{ant-prefix}-dropdown-menu {
border: 0; border: 0;
box-shadow: none; box-shadow: none;
border-radius: @border-radius-base @border-radius-base 0 0; border-radius: @border-radius-base @border-radius-base 0 0;
@ -320,8 +320,8 @@
box-shadow: @box-shadow-base; box-shadow: @box-shadow-base;
} }
.ant-dropdown-submenu-contain-selected { .@{ant-prefix}-dropdown-submenu-contain-selected {
.ant-dropdown-menu-submenu-title:after { .@{ant-prefix}-dropdown-menu-submenu-title:after {
color: @primary-color; color: @primary-color;
font-weight: bold; font-weight: bold;
text-shadow: 0 0 2px tint(@primary-color, 80%); text-shadow: 0 0 2px tint(@primary-color, 80%);
@ -329,12 +329,12 @@
} }
} }
.ant-dropdown-menu-item { .@{ant-prefix}-dropdown-menu-item {
overflow: hidden; overflow: hidden;
} }
> .ant-dropdown-menu > .ant-dropdown-menu-item:last-child, > .@{ant-prefix}-dropdown-menu > .@{ant-prefix}-dropdown-menu-item:last-child,
> .ant-dropdown-menu > .ant-dropdown-menu-submenu:last-child .ant-dropdown-menu-submenu-title { > .@{ant-prefix}-dropdown-menu > .@{ant-prefix}-dropdown-menu-submenu:last-child .@{ant-prefix}-dropdown-menu-submenu-title {
border-radius: 0; border-radius: 0;
} }

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@tab-prefix-cls: ant-tabs; @tab-prefix-cls: ~"@{ant-prefix}-tabs";
.@{tab-prefix-cls} { .@{tab-prefix-cls} {
box-sizing: border-box; box-sizing: border-box;
@ -174,7 +174,7 @@
color: shade(@primary-color, 5%); color: shade(@primary-color, 5%);
} }
.anticon { .@{iconfont-css-prefix} {
width: 14px; width: 14px;
height: 14px; height: 14px;
margin-right: 8px; margin-right: 8px;
@ -401,7 +401,7 @@
&&-card > &-bar &-nav-wrap { &&-card > &-bar &-nav-wrap {
margin-bottom: 0; margin-bottom: 0;
} }
&&-card > &-bar &-tab-inner .anticon-cross { &&-card > &-bar &-tab-inner .@{iconfont-css-prefix}-cross {
margin-right: 0; margin-right: 0;
color: #999; color: #999;
transition: all 0.3s @ease-in-out; transition: all 0.3s @ease-in-out;
@ -422,8 +422,8 @@
padding-right: 8px; padding-right: 8px;
} }
&&-card > &-bar &-tab-active .anticon-cross, &&-card > &-bar &-tab-active .@{iconfont-css-prefix}-cross,
&&-card > &-bar &-tab:hover .anticon-cross { &&-card > &-bar &-tab:hover .@{iconfont-css-prefix}-cross {
width: 16px; width: 16px;
transform: translateZ(0); transform: translateZ(0);
} }

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@tag-prefix-cls: ant-tag; @tag-prefix-cls: ~"@{ant-prefix}-tag";
.@{tag-prefix-cls} { .@{tag-prefix-cls} {
display: inline-block; display: inline-block;
@ -37,7 +37,7 @@
} }
} }
.anticon-cross { .@{iconfont-css-prefix}-cross {
.iconfont-size-under-12px(10px); .iconfont-size-under-12px(10px);
cursor: pointer; cursor: pointer;
font-weight: bold; font-weight: bold;
@ -59,8 +59,8 @@
&, &,
a, a,
a:hover, a:hover,
.anticon-cross, .@{iconfont-css-prefix}-cross,
.anticon-cross:hover { .@{iconfont-css-prefix}-cross:hover {
color: #fff; color: #fff;
} }
} }

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "../../input/style/mixin"; @import "../../input/style/mixin";
@timepicker-prefix-cls: ant-time-picker; @timepicker-prefix-cls: ~"@{ant-prefix}-time-picker";
.@{timepicker-prefix-cls}-panel { .@{timepicker-prefix-cls}-panel {
max-width: 168px; max-width: 168px;

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@timeline-prefix-cls: ant-timeline; @timeline-prefix-cls: ~"@{ant-prefix}-timeline";
@timeline-color: @border-color-split; @timeline-color: @border-color-split;
.@{timeline-prefix-cls} { .@{timeline-prefix-cls} {

View File

@ -1,7 +1,7 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@tooltip-prefix-cls: ant-tooltip; @tooltip-prefix-cls: ~"@{ant-prefix}-tooltip";
//** Tooltip max width //** Tooltip max width
@tooltip-max-width: 250px; @tooltip-max-width: 250px;
//** Tooltip text color //** Tooltip text color

View File

@ -216,15 +216,16 @@ export default class TransferList extends React.Component<TransferListProps, any
} }
const checkStatus = this.getCheckStatus(filteredDataSource); const checkStatus = this.getCheckStatus(filteredDataSource);
const outerPrefixCls = prefixCls.replace('-list', '');
return ( return (
<div className={listCls} style={style}> <div className={listCls} style={style}>
<div className={`${prefixCls}-header`}> <div className={`${prefixCls}-header`}>
{this.renderCheckbox({ {this.renderCheckbox({
prefixCls: 'ant-transfer', prefixCls: outerPrefixCls,
checked: checkStatus === 'all', checked: checkStatus === 'all',
checkPart: checkStatus === 'part', checkPart: checkStatus === 'part',
checkable: <span className={'ant-transfer-checkbox-inner'}></span>, checkable: <span className={`${outerPrefixCls}-checkbox-inner`}></span>,
filteredDataSource, filteredDataSource,
disabled: false, disabled: false,
})} })}

View File

@ -1,5 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import Icon from '../icon'; import Icon from '../icon';
import Input from '../input';
function noop() { function noop() {
} }
@ -31,7 +33,7 @@ export default class Search extends React.Component<SearchProps, any> {
const { placeholder, value, prefixCls } = this.props; const { placeholder, value, prefixCls } = this.props;
return ( return (
<div> <div>
<input placeholder={placeholder} className={`${prefixCls} ant-input`} value={value} ref="input" <Input placeholder={placeholder} className={prefixCls} value={value} ref="input"
onChange={this.handleChange} onChange={this.handleChange}
/> />
{value && value.length > 0 ? {value && value.length > 0 ?

View File

@ -2,8 +2,8 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@import "../../checkbox/style/mixin"; @import "../../checkbox/style/mixin";
@transfer-prefix-cls: ant-transfer; @transfer-prefix-cls: ~"@{ant-prefix}-transfer";
.antCheckboxFn(@checkbox-prefix-cls: ant-transfer-checkbox); .antCheckboxFn(@checkbox-prefix-cls: ~"@{ant-prefix}-transfer-checkbox");
.@{transfer-prefix-cls} { .@{transfer-prefix-cls} {
position: relative; position: relative;
@ -35,7 +35,7 @@
line-height: 32px; line-height: 32px;
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
.anticon { .@{iconfont-css-prefix} {
transition: all .3s; transition: all .3s;
font-size: 12px; font-size: 12px;
color: #ccc; color: #ccc;
@ -126,7 +126,7 @@
margin: 0 8px; margin: 0 8px;
vertical-align: middle; vertical-align: middle;
.ant-btn { .@{ant-prefix}-btn {
float: left; float: left;
clear: both; clear: both;
@ -134,7 +134,7 @@
margin-bottom: 4px; margin-bottom: 4px;
} }
.anticon { .@{iconfont-css-prefix} {
.iconfont-size-under-12px(8px); .iconfont-size-under-12px(8px);
} }
} }

View File

@ -3,9 +3,9 @@
@import "../../tree/style/mixin"; @import "../../tree/style/mixin";
@import "../../checkbox/style/mixin"; @import "../../checkbox/style/mixin";
@select-tree-prefix-cls: ant-select-tree; @select-tree-prefix-cls: ~"@{ant-prefix}-select-tree";
.antCheckboxFn(@checkbox-prefix-cls: ant-select-tree-checkbox); .antCheckboxFn(@checkbox-prefix-cls: ~"@{ant-prefix}-select-tree-checkbox");
.@{select-tree-prefix-cls} { .@{select-tree-prefix-cls} {
margin: 0; margin: 0;
@ -115,14 +115,14 @@
} }
} }
.@{select-tree-prefix-cls}-dropdown .ant-select-dropdown-search + span { .@{select-tree-prefix-cls}-dropdown .@{ant-prefix}-select-dropdown-search + span {
padding: 7px 15px; padding: 7px 15px;
color: #ccc; color: #ccc;
cursor: not-allowed; cursor: not-allowed;
display: block; display: block;
} }
.ant-select-not-found { .@{ant-prefix}-select-not-found {
cursor: not-allowed; cursor: not-allowed;
color: #ccc; color: #ccc;
padding: 7px 15px; padding: 7px 15px;

View File

@ -3,8 +3,8 @@
@import "../../checkbox/style/mixin"; @import "../../checkbox/style/mixin";
@import "./mixin"; @import "./mixin";
@tree-prefix-cls: ant-tree; @tree-prefix-cls: ~"@{ant-prefix}-tree";
.antCheckboxFn(@checkbox-prefix-cls: ant-tree-checkbox); .antCheckboxFn(@checkbox-prefix-cls: ~"@{ant-prefix}-tree-checkbox");
.@{tree-prefix-cls} { .@{tree-prefix-cls} {
margin: 0; margin: 0;

View File

@ -3,7 +3,6 @@ import RcUpload from 'rc-upload';
import UploadList from './uploadList'; import UploadList from './uploadList';
import getFileItem from './getFileItem'; import getFileItem from './getFileItem';
import classNames from 'classnames'; import classNames from 'classnames';
const prefixCls = 'ant-upload';
import assign from 'object-assign'; import assign from 'object-assign';
import { UploadProps } from './interface'; import { UploadProps } from './interface';
@ -65,7 +64,7 @@ export default class Upload extends React.Component<UploadProps, any> {
static Dragger = Dragger; static Dragger = Dragger;
static defaultProps = { static defaultProps = {
prefixCls: 'ant-upload-btn', prefixCls: 'ant-upload',
type: 'select', type: 'select',
// do not set // do not set
// name: '', // name: '',
@ -249,6 +248,7 @@ export default class Upload extends React.Component<UploadProps, any> {
} }
render() { render() {
const { prefixCls } = this.props;
let type = this.props.type || 'select'; let type = this.props.type || 'select';
let props = assign({}, this.props, { let props = assign({}, this.props, {
onStart: this.onStart, onStart: this.onStart,

View File

@ -44,6 +44,7 @@ export interface UploadProps {
supportServerRender?: boolean; supportServerRender?: boolean;
style?: React.CSSProperties; style?: React.CSSProperties;
disabled?: boolean; disabled?: boolean;
prefixCls?: string;
} }
export interface UploadListProps { export interface UploadListProps {
@ -52,4 +53,5 @@ export interface UploadListProps {
onRemove?: (file: File) => void; onRemove?: (file: File) => void;
items?: Array<File>; items?: Array<File>;
progressAttr?: Object; progressAttr?: Object;
prefixCls?: string;
} }

View File

@ -1,8 +1,8 @@
@import "../../style/themes/default"; @import "../../style/themes/default";
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@upload-prefix-cls: ant-upload; @upload-prefix-cls: ~"@{ant-prefix}-upload";
@upload-item: ant-upload-list-item; @upload-item: ~"@{ant-prefix}-upload-list-item";
@upload-pictrue-card-size: 96px; @upload-pictrue-card-size: 96px;
.@{upload-prefix-cls} { .@{upload-prefix-cls} {
@ -75,7 +75,7 @@
} }
p.@{upload-prefix-cls}-drag-icon { p.@{upload-prefix-cls}-drag-icon {
.anticon { .@{iconfont-css-prefix} {
font-size: 80px; font-size: 80px;
margin-top: -5px; margin-top: -5px;
color: tint(@primary-color, 20%); color: tint(@primary-color, 20%);
@ -90,7 +90,7 @@
font-size: 12px; font-size: 12px;
color: #999; color: #999;
} }
.anticon-plus { .@{iconfont-css-prefix}-plus {
font-size: 30px; font-size: 30px;
transition: all 0.3s ease; transition: all 0.3s ease;
color: #ccc; color: #ccc;
@ -98,7 +98,7 @@
color: #999; color: #999;
} }
} }
&:hover .anticon-plus { &:hover .@{iconfont-css-prefix}-plus {
color: #999; color: #999;
} }
} }
@ -117,12 +117,12 @@
padding: 0 4px; padding: 0 4px;
transition: background-color 0.3s ease; transition: background-color 0.3s ease;
.anticon-paper-clip { .@{iconfont-css-prefix}-paper-clip {
margin-right: 4px; margin-right: 4px;
font-size: 12px; font-size: 12px;
color: #999; color: #999;
} }
.anticon-cross { .@{iconfont-css-prefix}-cross {
.iconfont-size-under-12px(10px); .iconfont-size-under-12px(10px);
transition: all 0.3s ease; transition: all 0.3s ease;
opacity: 0; opacity: 0;
@ -140,16 +140,16 @@
background-color: tint(@primary-color, 90%); background-color: tint(@primary-color, 90%);
} }
&:hover .anticon-cross { &:hover .@{iconfont-css-prefix}-cross {
opacity: 1; opacity: 1;
} }
&-error, &-error,
&-error .anticon-paper-clip { &-error .@{iconfont-css-prefix}-paper-clip {
color: @error-color; color: @error-color;
} }
&-error .anticon-cross { &-error .@{iconfont-css-prefix}-cross {
opacity: 1; opacity: 1;
} }
@ -158,7 +158,7 @@
margin-top: -2px; margin-top: -2px;
margin-bottom: 1px; margin-bottom: 1px;
font-size: 12px; font-size: 12px;
.ant-progress-line-inner { .@{ant-prefix}-progress-line-inner {
vertical-align: middle; vertical-align: middle;
} }
} }
@ -203,7 +203,7 @@
display: block; display: block;
} }
.@{upload-item}-thumbnail.anticon:before { .@{upload-item}-thumbnail.@{iconfont-css-prefix}:before {
line-height: 48px; line-height: 48px;
font-size: 24px; font-size: 24px;
color: #999; color: #999;
@ -232,7 +232,7 @@
margin-top: 0; margin-top: 0;
} }
.anticon-cross { .@{iconfont-css-prefix}-cross {
position: absolute; position: absolute;
right: 8px; right: 8px;
top: 8px; top: 8px;
@ -265,8 +265,8 @@
height: 100%; height: 100%;
} }
.anticon-eye-o, .@{iconfont-css-prefix}-eye-o,
.anticon-delete { .@{iconfont-css-prefix}-delete {
position: absolute; position: absolute;
left: 50%; left: 50%;
top: 50%; top: 50%;
@ -286,7 +286,7 @@
} }
} }
.anticon-delete { .@{iconfont-css-prefix}-delete {
left: 50%; left: 50%;
margin-left: 6px; margin-left: 6px;
} }
@ -296,8 +296,8 @@
opacity: .8; opacity: .8;
} }
.anticon-eye-o, .@{iconfont-css-prefix}-eye-o,
.anticon-delete { .@{iconfont-css-prefix}-delete {
opacity: 1; opacity: 1;
} }
} }
@ -323,8 +323,8 @@
.@{upload-item}-info { .@{upload-item}-info {
height: auto; height: auto;
&:before, &:before,
.anticon-eye-o, .@{iconfont-css-prefix}-eye-o,
.anticon-delete { .@{iconfont-css-prefix}-delete {
display: none; display: none;
} }
} }

View File

@ -1,7 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import Animate from 'rc-animate'; import Animate from 'rc-animate';
import Icon from '../icon'; import Icon from '../icon';
const prefixCls = 'ant-upload';
import Progress from '../progress'; import Progress from '../progress';
import classNames from 'classnames'; import classNames from 'classnames';
import { UploadListProps } from './interface'; import { UploadListProps } from './interface';
@ -21,6 +20,7 @@ export default class UploadList extends React.Component<UploadListProps, any> {
strokeWidth: 3, strokeWidth: 3,
showInfo: false, showInfo: false,
}, },
prefixCls: 'ant-upload',
}; };
handleClose = (file) => { handleClose = (file) => {
@ -59,6 +59,7 @@ export default class UploadList extends React.Component<UploadListProps, any> {
} }
render() { render() {
const { prefixCls } = this.props;
let list = this.props.items.map(file => { let list = this.props.items.map(file => {
let progress; let progress;
let icon = <Icon type="paper-clip" />; let icon = <Icon type="paper-clip" />;