update 3.4.0
parent
25d1703092
commit
89bd5afa6e
|
@ -0,0 +1,4 @@
|
|||
// https://github.com/moment/moment/issues/3650
|
||||
export default function interopDefault (m) {
|
||||
return m.default || m
|
||||
}
|
|
@ -128,6 +128,20 @@ export default {
|
|||
}
|
||||
this.setState({ placeholderStyle: placeholderStyle })
|
||||
},
|
||||
syncPlaceholderStyle (e) {
|
||||
const { affixStyle } = this
|
||||
if (!affixStyle) {
|
||||
return
|
||||
}
|
||||
this.$refs.placeholderNode.style.cssText = ''
|
||||
this.setAffixStyle(e, {
|
||||
...affixStyle,
|
||||
width: this.$refs.placeholderNode.offsetWidth + 'px',
|
||||
})
|
||||
this.setPlaceholderStyle({
|
||||
width: this.$refs.placeholderNode.offsetWidth + 'px',
|
||||
})
|
||||
},
|
||||
|
||||
updatePosition (e) {
|
||||
let { offsetTop } = this
|
||||
|
@ -200,6 +214,9 @@ export default {
|
|||
}
|
||||
this.setPlaceholderStyle(null)
|
||||
}
|
||||
if (e.type === 'resize') {
|
||||
this.syncPlaceholderStyle(e)
|
||||
}
|
||||
},
|
||||
setTargetEventListeners (getTarget) {
|
||||
const target = getTarget()
|
||||
|
@ -233,7 +250,7 @@ export default {
|
|||
attrs: omit($props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target']),
|
||||
}
|
||||
return (
|
||||
<div {...props} style={placeholderStyle}>
|
||||
<div {...props} style={placeholderStyle} ref='placeholderNode'>
|
||||
<div class={className} ref='fixedNode' style={affixStyle}>
|
||||
{$slots.default}
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| afterClose | Called when close animation is finished | () => void | - |
|
||||
| banner | Whether to show as banner | boolean | false |
|
||||
| closable | Whether Alert can be closed | boolean | - |
|
||||
| closeText | Close text to show | string\|slot | - |
|
||||
|
@ -15,4 +16,5 @@
|
|||
### events
|
||||
| Events Name | Description | Arguments |
|
||||
| --- | --- | --- |
|
||||
| close | Callback when Alert is closed | Function |
|
||||
| close | Callback when Alert is closed | (e: MouseEvent) => void |
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import BaseMixin from '../_util/BaseMixin'
|
|||
import PropTypes from '../_util/vue-types'
|
||||
import getTransitionProps from '../_util/getTransitionProps'
|
||||
import { getComponentFromProp } from '../_util/props-util'
|
||||
|
||||
function noop () { }
|
||||
export const AlertProps = {
|
||||
/**
|
||||
* Type of Alert styles, options:`success`, `info`, `warning`, `error`
|
||||
|
@ -21,6 +21,8 @@ export const AlertProps = {
|
|||
description: PropTypes.any,
|
||||
/** Callback when close Alert */
|
||||
// onClose?: React.MouseEventHandler<HTMLAnchorElement>;
|
||||
/** Trigger when animation ending of Alert */
|
||||
afterClose: PropTypes.func.def(noop),
|
||||
/** Whether to show icon */
|
||||
showIcon: PropTypes.bool,
|
||||
iconType: PropTypes.string,
|
||||
|
@ -57,6 +59,7 @@ export default {
|
|||
closed: true,
|
||||
closing: true,
|
||||
})
|
||||
this.afterClose()
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| afterClose | 关闭动画结束后的回掉 | () => void | - |
|
||||
| banner | 是否用作顶部公告 | boolean | false |
|
||||
| closable | 默认不显示关闭按钮 | boolean | 无 |
|
||||
| closeText | 自定义关闭按钮 | string\|slot | 无 |
|
||||
|
@ -15,4 +16,4 @@
|
|||
### 事件
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
| --- | --- | --- |
|
||||
| close | 关闭时触发的回调函数 | Function |
|
||||
| close | 关闭时触发的回调函数 | (e: MouseEvent) => void |
|
||||
|
|
|
@ -18,8 +18,15 @@ export default {
|
|||
},
|
||||
clicked: false,
|
||||
sLoading: !!this.loading,
|
||||
hasTwoCNChar: false,
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.fixTwoCNChar()
|
||||
},
|
||||
updated () {
|
||||
this.fixTwoCNChar()
|
||||
},
|
||||
watch: {
|
||||
loading (val) {
|
||||
clearTimeout(this.delayTimeout)
|
||||
|
@ -32,7 +39,8 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
classes () {
|
||||
const { prefixCls, type, shape, size, sLoading, ghost, clicked, sizeMap } = this
|
||||
const { prefixCls, type, shape, size, hasTwoCNChar,
|
||||
sLoading, ghost, clicked, sizeMap } = this
|
||||
const sizeCls = sizeMap[size] || ''
|
||||
return {
|
||||
[`${prefixCls}`]: true,
|
||||
|
@ -42,6 +50,7 @@ export default {
|
|||
[`${prefixCls}-loading`]: sLoading,
|
||||
[`${prefixCls}-clicked`]: clicked,
|
||||
[`${prefixCls}-background-ghost`]: ghost || type === 'ghost',
|
||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar,
|
||||
}
|
||||
},
|
||||
iconType () {
|
||||
|
@ -50,6 +59,18 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
fixTwoCNChar () {
|
||||
// Fix for HOC usage like <FormatMessage />
|
||||
const node = this.$el
|
||||
const buttonText = node.textContent || node.innerText
|
||||
if (this.isNeedInserted() && isTwoCNChar(buttonText)) {
|
||||
if (!this.hasTwoCNChar) {
|
||||
this.hasTwoCNChar = true
|
||||
}
|
||||
} else if (this.hasTwoCNChar) {
|
||||
this.hasTwoCNChar = false
|
||||
}
|
||||
},
|
||||
handleClick (event) {
|
||||
this.clicked = true
|
||||
clearTimeout(this.timeout)
|
||||
|
@ -67,9 +88,16 @@ export default {
|
|||
}
|
||||
return child
|
||||
},
|
||||
isNeedInserted () {
|
||||
const { loading, icon, $slots } = this
|
||||
const iconType = loading ? 'loading' : icon
|
||||
return $slots.default && $slots.default.length === 1 && (!iconType || iconType === 'loading')
|
||||
},
|
||||
},
|
||||
render () {
|
||||
const { htmlType, classes, disabled, handleClick, iconType, $slots, $attrs, $listeners } = this
|
||||
const { htmlType, classes,
|
||||
disabled, handleClick, iconType,
|
||||
$slots, $attrs, $listeners } = this
|
||||
const buttonProps = {
|
||||
props: {
|
||||
},
|
||||
|
@ -84,8 +112,7 @@ export default {
|
|||
click: handleClick,
|
||||
},
|
||||
}
|
||||
const needInserted = $slots.default && $slots.default.length === 1 && (!iconType || iconType === 'loading')
|
||||
const kids = $slots.default && $slots.default.length === 1 ? this.insertSpace($slots.default[0], needInserted) : $slots.default
|
||||
const kids = $slots.default && $slots.default.length === 1 ? this.insertSpace($slots.default[0], this.isNeedInserted()) : $slots.default
|
||||
return (
|
||||
<button {...buttonProps}>
|
||||
{iconType ? <Icon type={iconType}></Icon> : null}
|
||||
|
|
|
@ -54,11 +54,14 @@
|
|||
.button-variant-danger(@color; @background; @border) {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
&:hover {
|
||||
.button-color(@btn-primary-color; ~`colorPalette("@{color}", 5)`; ~`colorPalette("@{color}", 5)`);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.button-color(~`colorPalette("@{color}", 5)`; #fff; ~`colorPalette("@{color}", 5)`);
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(@btn-primary-color; ~`colorPalette("@{color}", 7)`; ~`colorPalette("@{color}", 7)`);
|
||||
|
@ -108,6 +111,7 @@
|
|||
display: inline-block;
|
||||
> .@{btnClassName} {
|
||||
position: relative;
|
||||
line-height: @btn-height-base - 2px;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
|
@ -124,10 +128,12 @@
|
|||
// size
|
||||
&-lg > .@{btnClassName} {
|
||||
.button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; @btn-border-radius-base);
|
||||
line-height: @btn-height-lg - 2px;
|
||||
}
|
||||
|
||||
&-sm > .@{btnClassName} {
|
||||
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; @btn-border-radius-sm);
|
||||
line-height: @btn-height-sm - 2px;
|
||||
> .@{iconfont-css-prefix} {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
|
@ -198,7 +204,8 @@
|
|||
&:focus,
|
||||
&:active,
|
||||
&.active {
|
||||
background: #fff;
|
||||
background: @btn-default-bg;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ export const HeaderProps = {
|
|||
// onValueChange: PropTypes.(value: moment.Moment) => void,
|
||||
// onTypeChange: PropTypes.(type: string) => void,
|
||||
value: PropTypes.any,
|
||||
validRange: PropTypes.array,
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -28,9 +29,20 @@ export default {
|
|||
// private calenderHeaderNode: HTMLDivElement;
|
||||
methods: {
|
||||
getYearSelectElement (year) {
|
||||
const { yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen } = this
|
||||
const start = year - yearSelectOffset
|
||||
const end = start + yearSelectTotal
|
||||
const {
|
||||
yearSelectOffset,
|
||||
yearSelectTotal,
|
||||
locale,
|
||||
prefixCls,
|
||||
fullscreen,
|
||||
validRange,
|
||||
} = this
|
||||
let start = year - yearSelectOffset
|
||||
let end = start + yearSelectTotal
|
||||
if (validRange) {
|
||||
start = validRange[0].get('year')
|
||||
end = validRange[1].get('year') + 1
|
||||
}
|
||||
const suffix = locale.year === '年' ? '年' : ''
|
||||
|
||||
const options = []
|
||||
|
@ -63,10 +75,20 @@ export default {
|
|||
},
|
||||
|
||||
getMonthSelectElement (month, months) {
|
||||
const { prefixCls, fullscreen } = this
|
||||
const { prefixCls, fullscreen, validRange, value } = this
|
||||
const options = []
|
||||
|
||||
for (let index = 0; index < 12; index++) {
|
||||
let start = 0
|
||||
let end = 12
|
||||
if (validRange) {
|
||||
const [rangeStart, rangeEnd] = validRange
|
||||
const currentYear = value.get('year')
|
||||
if (rangeEnd.get('year') === currentYear) {
|
||||
end = rangeEnd.get('month') + 1
|
||||
} else {
|
||||
start = rangeStart.get('month')
|
||||
}
|
||||
}
|
||||
for (let index = start; index < end; index++) {
|
||||
options.push(<Option key={`${index}`}>{months[index]}</Option>)
|
||||
}
|
||||
|
||||
|
@ -85,8 +107,21 @@ export default {
|
|||
},
|
||||
|
||||
onYearChange (year) {
|
||||
const newValue = this.value.clone()
|
||||
const { value, validRange } = this
|
||||
const newValue = value.clone()
|
||||
newValue.year(parseInt(year, 10))
|
||||
// switch the month so that it remains within range when year changes
|
||||
if (validRange) {
|
||||
const [start, end] = validRange
|
||||
const newYear = newValue.get('year')
|
||||
const newMonth = newValue.get('month')
|
||||
if (newYear === end.get('year') && newMonth > end.get('month')) {
|
||||
newValue.month(end.get('month'))
|
||||
}
|
||||
if (newYear === start.get('year') && newMonth < start.get('month')) {
|
||||
newValue.month(start.get('month'))
|
||||
}
|
||||
}
|
||||
this.$emit('valueChange', newValue)
|
||||
},
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ customize the progress dot by setting a scoped slot
|
|||
| mode | The display mode of the calendar | `month` \| `year` | `month` |
|
||||
| monthCellRender | Customize the display of the month cell by setting a scoped slot, the returned content will be appended to the cell | function(date: moment) | - |
|
||||
| monthFullCellRender | Customize the display of the month cell by setting a scoped slot, the returned content will override the cell | function(date: moment) | - |
|
||||
| validRange | to set valid range | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - |
|
||||
| value(v-model) | The current selected date | [moment](http://momentjs.com/) | current date |
|
||||
|
||||
### events
|
||||
|
|
|
@ -7,7 +7,7 @@ import FullCalendar from '../vc-calendar/src/FullCalendar'
|
|||
import LocaleReceiver from '../locale-provider/LocaleReceiver'
|
||||
import { PREFIX_CLS } from './Constants'
|
||||
import Header from './Header'
|
||||
import callMoment from '../_util/callMoment'
|
||||
import interopDefault from '../_util/interopDefault'
|
||||
import enUS from './locale/en_US'
|
||||
|
||||
export { HeaderProps } from './Header'
|
||||
|
@ -26,6 +26,9 @@ export const MomentType = {
|
|||
return moment.isMoment(value)
|
||||
},
|
||||
}
|
||||
function isMomentArray (value) {
|
||||
return Array.isArray(value) && !!value.find((val) => moment.isMoment(val))
|
||||
}
|
||||
export const CalendarMode = PropTypes.oneOf(['month', 'year'])
|
||||
|
||||
export const CalendarProps = () => ({
|
||||
|
@ -42,6 +45,7 @@ export const CalendarProps = () => ({
|
|||
// onPanelChange?: (date?: moment.Moment, mode?: CalendarMode) => void;
|
||||
// onSelect?: (date?: moment.Moment) => void;
|
||||
disabledDate: PropTypes.func,
|
||||
validRange: PropTypes.custom(isMomentArray),
|
||||
})
|
||||
|
||||
export default {
|
||||
|
@ -57,8 +61,8 @@ export default {
|
|||
event: 'change',
|
||||
},
|
||||
data () {
|
||||
const value = this.value || this.defaultValue || callMoment(moment)
|
||||
if (!moment.isMoment(value)) {
|
||||
const value = this.value || this.defaultValue || interopDefault(moment)()
|
||||
if (!interopDefault(moment).isMoment(value)) {
|
||||
throw new Error(
|
||||
'The value/defaultValue of Calendar must be a moment object, ',
|
||||
)
|
||||
|
@ -149,6 +153,22 @@ export default {
|
|||
onSelect (value) {
|
||||
this.setValue(value, 'select')
|
||||
},
|
||||
getDateRange (
|
||||
validRange,
|
||||
disabledDate,
|
||||
) {
|
||||
return (current) => {
|
||||
if (!current) {
|
||||
return false
|
||||
}
|
||||
const [startDate, endDate] = validRange
|
||||
const inRange = !current.isBetween(startDate, endDate, 'days', '[]')
|
||||
if (disabledDate) {
|
||||
return (disabledDate(current) || inRange)
|
||||
}
|
||||
return inRange
|
||||
}
|
||||
},
|
||||
|
||||
renderCalendar (locale, localeCode) {
|
||||
const props = getOptionProps(this)
|
||||
|
@ -166,6 +186,12 @@ export default {
|
|||
|
||||
const monthCellRender = monthFullCellRender || $scopedSlots.monthFullCellRender || this.monthCellRender2
|
||||
const dateCellRender = dateFullCellRender || $scopedSlots.dateFullCellRender || this.dateCellRender2
|
||||
|
||||
let disabledDate = props.disabledDate
|
||||
|
||||
if (props.validRange) {
|
||||
disabledDate = this.getDateRange(props.validRange, disabledDate)
|
||||
}
|
||||
const fullCalendarProps = {
|
||||
props: {
|
||||
...props,
|
||||
|
@ -177,6 +203,7 @@ export default {
|
|||
value: value,
|
||||
monthCellRender: monthCellRender,
|
||||
dateCellRender: dateCellRender,
|
||||
disabledDate,
|
||||
},
|
||||
on: {
|
||||
...$listeners,
|
||||
|
@ -193,6 +220,7 @@ export default {
|
|||
prefixCls={prefixCls}
|
||||
onTypeChange={this.onHeaderTypeChange}
|
||||
onValueChange={this.onHeaderValueChange}
|
||||
validRange={props.validRange}
|
||||
/>
|
||||
<FullCalendar {...fullCalendarProps}/>
|
||||
</div>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
| mode | 初始模式,`month/year` | string | month |
|
||||
| monthCellRender | 作用域插槽,自定义渲染月单元格,返回内容会被追加到单元格 | function(date: moment) | 无 |
|
||||
| monthFullCellRender | 作用域插槽,自定义渲染月单元格,返回内容覆盖单元格 | function(date: moment) | 无 |
|
||||
| validRange | 设置可以显示的日期 | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | 无 |
|
||||
| value(v-model) | 展示日期 | [moment](http://momentjs.com/) | 当前日期 |
|
||||
|
||||
### 事件
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import sl_SI from '../../date-picker/locale/sl_SI'
|
||||
export default sl_SI
|
|
@ -21,6 +21,8 @@ export default {
|
|||
type: PropTypes.string,
|
||||
actions: PropTypes.any,
|
||||
tabList: PropTypes.array,
|
||||
activeTabKey: PropTypes.string,
|
||||
defaultActiveTabKey: PropTypes.string,
|
||||
},
|
||||
data () {
|
||||
this.updateWiderPaddingCalled = false
|
||||
|
@ -80,7 +82,7 @@ export default {
|
|||
render () {
|
||||
const {
|
||||
prefixCls = 'ant-card', extra, bodyStyle, title, loading,
|
||||
bordered = true, type, tabList, hoverable,
|
||||
bordered = true, type, tabList, hoverable, activeTabKey, defaultActiveTabKey,
|
||||
} = this.$props
|
||||
|
||||
const { $slots } = this
|
||||
|
@ -120,9 +122,23 @@ export default {
|
|||
</div>
|
||||
)
|
||||
|
||||
const hasActiveTabKey = activeTabKey !== undefined
|
||||
const tabsProps = {
|
||||
props: {
|
||||
size: 'large',
|
||||
[hasActiveTabKey ? 'activeKey' : 'defaultActiveKey']: hasActiveTabKey
|
||||
? activeTabKey
|
||||
: defaultActiveTabKey,
|
||||
},
|
||||
on: {
|
||||
change: this.onHandleTabChange,
|
||||
},
|
||||
class: `${prefixCls}-head-tabs`,
|
||||
}
|
||||
|
||||
let head
|
||||
const tabs = tabList && tabList.length ? (
|
||||
<Tabs class={`${prefixCls}-head-tabs`} size='large' onChange={this.onHandleTabChange}>
|
||||
<Tabs {...tabsProps}>
|
||||
{tabList.map(item => <TabPane tab={item.tab} key={item.key} />)}
|
||||
</Tabs>
|
||||
) : null
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[>_<]:
|
||||
这个卡片没起作用还报错!一堆的那种!!!
|
||||
|
||||
<cn>
|
||||
#### 网格型内嵌卡片
|
||||
一种常见的卡片内容区隔模式。
|
||||
|
@ -13,25 +10,14 @@ Grid style card content.
|
|||
|
||||
```html
|
||||
<template>
|
||||
<Card title="Card Title">
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
<CardGrid style="width:25%;textAlign:'center'">Content</CardGrid>
|
||||
</Card>
|
||||
<a-card title="Card Title">
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
<a-card-grid style="width:25%;textAlign:'center'">Content</a-card-grid>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '../style'
|
||||
import { Card } from 'antd'
|
||||
export default {
|
||||
components: {
|
||||
Card,
|
||||
CardGrid: Card.Grid,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#### 预加载的卡片
|
||||
数据读入前会有文本块样式
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Loading card
|
||||
Shows a loading indirector while the contents of the card is being featched
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
```html
|
||||
<template>
|
||||
<Card
|
||||
<a-card
|
||||
hoverable
|
||||
style="width: 300px"
|
||||
>
|
||||
|
@ -20,28 +20,15 @@
|
|||
slot="cover"
|
||||
/>
|
||||
<ul class="ant-card-actions" slot="actions">
|
||||
<li style="width: 33.3333%;"><Icon type="setting" /></li>
|
||||
<li style="width: 33.3333%;"><Icon type="edit" /></li>
|
||||
<li style="width: 33.3333%;"> <Icon type="ellipsis" /></li>
|
||||
<li style="width: 33.3333%;"><a-icon type="setting" /></li>
|
||||
<li style="width: 33.3333%;"><a-icon type="edit" /></li>
|
||||
<li style="width: 33.3333%;"> <a-icon type="ellipsis" /></li>
|
||||
</ul>
|
||||
<Meta
|
||||
<a-card-meta
|
||||
title="Card title"
|
||||
description="This is the description">
|
||||
<Avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
</Meta>
|
||||
</Card>
|
||||
<a-avatar slot="avatar" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
</a-card-meta>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '../style'
|
||||
import { Card, Icon, Avatar } from 'antd'
|
||||
export default {
|
||||
components: {
|
||||
Card,
|
||||
Icon,
|
||||
Avatar,
|
||||
Meta: Card.Meta,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#### 无边框
|
||||
在灰色背景上使用无边框的卡片
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### No border
|
||||
A borderless card on a gray background.
|
||||
|
@ -10,21 +11,12 @@
|
|||
```html
|
||||
<template>
|
||||
<div style="background:#ECECEC; padding:30px">
|
||||
<Card title="Card title" :bordered="false" style="width: 300px">
|
||||
<a-card title="Card title" :bordered="false" style="width: 300px">
|
||||
<p>Card content</p>
|
||||
<p>Card content</p>
|
||||
<p>Card content</p>
|
||||
</Card>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '../style'
|
||||
import { Card } from 'antd'
|
||||
export default {
|
||||
components: {
|
||||
Card,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<Card
|
||||
<a-card
|
||||
style="width:100%"
|
||||
title="Card title"
|
||||
:tabList="tabList"
|
||||
|
@ -20,21 +20,22 @@
|
|||
>
|
||||
<a href="#" slot="extra">More</a>
|
||||
{{contentList[key]}}
|
||||
</Card>
|
||||
</a-card>
|
||||
<br /><br />
|
||||
<Card
|
||||
<a-card
|
||||
style="width:100%"
|
||||
:tabList="tabListNoTitle"
|
||||
:activeTabKey="noTitleKey"
|
||||
@tabChange="key => onTabChange(key, 'noTitleKey')"
|
||||
>
|
||||
<div v-html="contentListNoTitle[noTitleKey]"></div>
|
||||
</Card>
|
||||
<p v-if="noTitleKey === 'article'">article content</p>
|
||||
<p v-else="noTitleKey === 'app'">app content</p>
|
||||
<p v-else="noTitleKey === 'project'">project content</p>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '../style'
|
||||
import { Card } from 'antd'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
|
@ -59,13 +60,8 @@ export default {
|
|||
key: 'project',
|
||||
tab: 'project',
|
||||
}],
|
||||
contentListNoTitle: {
|
||||
article: '<p>article content</p>',
|
||||
app: '<p>app content</p>',
|
||||
project: '<p>project content</p>',
|
||||
},
|
||||
key: 'tab1',
|
||||
noTitleKey: 'article',
|
||||
noTitleKey: 'app',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -74,9 +70,6 @@ export default {
|
|||
this[type] = key
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Card,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
| hoverable | Lift up when hovering card | boolean | false |
|
||||
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false |
|
||||
| tabList | List of TabPane's head. | Array<{key: string, tab: ReactNode}> | - |
|
||||
| activeTabKey | Current TabPane's key | string | - |
|
||||
| defaultActiveTabKey | Initial active TabPane's key, if `activeTabKey` is not set. | string | - |
|
||||
| title | Card title | string\|ReactNode | - |
|
||||
| type | Card style type, can be set to `inner` or not set | string | - |
|
||||
| onTabChange | Callback when tab is switched | (key) => void | - |
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
| hoverable | 鼠标移过时可浮起 | boolean | false |
|
||||
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false |
|
||||
| tabList | 页签标题列表 | Array<{key: string, tab: ReactNode}> | - |
|
||||
| activeTabKey | 当前激活页签的 key | string | - |
|
||||
| defaultActiveTabKey | 初始化选中页签的 key,如果没有设置 activeTabKey | string | 第一个页签 |
|
||||
| title | 卡片标题 | string\|ReactNode | - |
|
||||
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - |
|
||||
| onTabChange | 页签切换的回调 | (key) => void | - |
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
@card-prefix-cls: ~"@{ant-prefix}-card";
|
||||
@card-head-height: 48px;
|
||||
@card-hover-border: rgba(0, 0, 0, 0.09);
|
||||
|
||||
.@{card-prefix-cls} {
|
||||
.reset-component;
|
||||
|
@ -15,7 +16,7 @@
|
|||
cursor: pointer;
|
||||
&:hover {
|
||||
box-shadow: @card-shadow;
|
||||
border-color: rgba(0, 0, 0, 0.09);
|
||||
border-color: @card-hover-border;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,10 +135,16 @@
|
|||
|
||||
& > .anticon {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @text-color-secondary;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
|
|
|
@ -84,7 +84,10 @@ const MenuDivider = Menu.Divider
|
|||
const MenuItemGroup = Menu.ItemGroup
|
||||
export { Menu, MenuItem, SubMenu, MenuDivider, MenuItemGroup }
|
||||
|
||||
export { default as Card } from './card'
|
||||
import Card from './card'
|
||||
const CardMeta = Card.Meta
|
||||
const CardGrid = Card.Grid
|
||||
export { Card, CardMeta, CardGrid }
|
||||
|
||||
import Dropdown from './dropdown'
|
||||
const DropdownButton = Dropdown.Button
|
||||
|
|
|
@ -1,108 +1,111 @@
|
|||
/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors */
|
||||
.bezierEasingMixin() {
|
||||
@functions: ~`(function() {
|
||||
var NEWTON_ITERATIONS = 4;
|
||||
var NEWTON_MIN_SLOPE = 0.001;
|
||||
var SUBDIVISION_PRECISION = 0.0000001;
|
||||
var SUBDIVISION_MAX_ITERATIONS = 10;
|
||||
|
||||
var kSplineTableSize = 11;
|
||||
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
|
||||
|
||||
var float32ArraySupported = typeof Float32Array === 'function';
|
||||
|
||||
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
|
||||
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
|
||||
function C (aA1) { return 3.0 * aA1; }
|
||||
|
||||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
||||
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
|
||||
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
|
||||
|
||||
function binarySubdivide (aX, aA, aB, mX1, mX2) {
|
||||
var currentX, currentT, i = 0;
|
||||
do {
|
||||
currentT = aA + (aB - aA) / 2.0;
|
||||
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
||||
if (currentX > 0.0) {
|
||||
aB = currentT;
|
||||
} else {
|
||||
aA = currentT;
|
||||
}
|
||||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
|
||||
return currentT;
|
||||
}
|
||||
|
||||
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
|
||||
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
|
||||
var currentSlope = getSlope(aGuessT, mX1, mX2);
|
||||
if (currentSlope === 0.0) {
|
||||
return aGuessT;
|
||||
@functions: ~`(function() {
|
||||
var NEWTON_ITERATIONS = 4;
|
||||
var NEWTON_MIN_SLOPE = 0.001;
|
||||
var SUBDIVISION_PRECISION = 0.0000001;
|
||||
var SUBDIVISION_MAX_ITERATIONS = 10;
|
||||
|
||||
var kSplineTableSize = 11;
|
||||
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
|
||||
|
||||
var float32ArraySupported = typeof Float32Array === 'function';
|
||||
|
||||
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
|
||||
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
|
||||
function C (aA1) { return 3.0 * aA1; }
|
||||
|
||||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
||||
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
|
||||
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
|
||||
|
||||
function binarySubdivide (aX, aA, aB, mX1, mX2) {
|
||||
var currentX, currentT, i = 0;
|
||||
do {
|
||||
currentT = aA + (aB - aA) / 2.0;
|
||||
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
||||
if (currentX > 0.0) {
|
||||
aB = currentT;
|
||||
} else {
|
||||
aA = currentT;
|
||||
}
|
||||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
|
||||
return currentT;
|
||||
}
|
||||
|
||||
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
|
||||
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
|
||||
var currentSlope = getSlope(aGuessT, mX1, mX2);
|
||||
if (currentSlope === 0.0) {
|
||||
return aGuessT;
|
||||
}
|
||||
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
|
||||
aGuessT -= currentX / currentSlope;
|
||||
}
|
||||
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
|
||||
aGuessT -= currentX / currentSlope;
|
||||
}
|
||||
return aGuessT;
|
||||
}
|
||||
|
||||
var BezierEasing = function (mX1, mY1, mX2, mY2) {
|
||||
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
|
||||
throw new Error('bezier x values must be in [0, 1] range');
|
||||
return aGuessT;
|
||||
}
|
||||
|
||||
// Precompute samples table
|
||||
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
|
||||
if (mX1 !== mY1 || mX2 !== mY2) {
|
||||
for (var i = 0; i < kSplineTableSize; ++i) {
|
||||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
|
||||
|
||||
var BezierEasing = function (mX1, mY1, mX2, mY2) {
|
||||
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
|
||||
throw new Error('bezier x values must be in [0, 1] range');
|
||||
}
|
||||
}
|
||||
|
||||
function getTForX (aX) {
|
||||
var intervalStart = 0.0;
|
||||
var currentSample = 1;
|
||||
var lastSample = kSplineTableSize - 1;
|
||||
|
||||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
|
||||
intervalStart += kSampleStepSize;
|
||||
|
||||
// Precompute samples table
|
||||
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
|
||||
if (mX1 !== mY1 || mX2 !== mY2) {
|
||||
for (var i = 0; i < kSplineTableSize; ++i) {
|
||||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
--currentSample;
|
||||
|
||||
// Interpolate to provide an initial guess for t
|
||||
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
|
||||
var guessForT = intervalStart + dist * kSampleStepSize;
|
||||
|
||||
var initialSlope = getSlope(guessForT, mX1, mX2);
|
||||
if (initialSlope >= NEWTON_MIN_SLOPE) {
|
||||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
|
||||
} else if (initialSlope === 0.0) {
|
||||
return guessForT;
|
||||
} else {
|
||||
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
|
||||
|
||||
function getTForX (aX) {
|
||||
var intervalStart = 0.0;
|
||||
var currentSample = 1;
|
||||
var lastSample = kSplineTableSize - 1;
|
||||
|
||||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
|
||||
intervalStart += kSampleStepSize;
|
||||
}
|
||||
--currentSample;
|
||||
|
||||
// Interpolate to provide an initial guess for t
|
||||
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
|
||||
var guessForT = intervalStart + dist * kSampleStepSize;
|
||||
|
||||
var initialSlope = getSlope(guessForT, mX1, mX2);
|
||||
if (initialSlope >= NEWTON_MIN_SLOPE) {
|
||||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
|
||||
} else if (initialSlope === 0.0) {
|
||||
return guessForT;
|
||||
} else {
|
||||
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return function BezierEasing (x) {
|
||||
if (mX1 === mY1 && mX2 === mY2) {
|
||||
return x; // linear
|
||||
}
|
||||
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
||||
if (x === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x === 1) {
|
||||
return 1;
|
||||
}
|
||||
return calcBezier(getTForX(x), mY1, mY2);
|
||||
|
||||
return function BezierEasing (x) {
|
||||
if (mX1 === mY1 && mX2 === mY2) {
|
||||
return x; // linear
|
||||
}
|
||||
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
||||
if (x === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x === 1) {
|
||||
return 1;
|
||||
}
|
||||
return calcBezier(getTForX(x), mY1, mY2);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18);
|
||||
})()`;
|
||||
}
|
||||
// It is hacky way to make this function will be compiled preferentially by less
|
||||
// resolve error: `ReferenceError: colorPalette is not defined`
|
||||
// https://github.com/ant-design/ant-motion/issues/44
|
||||
.bezierEasingMixin();
|
||||
|
||||
this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18);
|
||||
// less 3 requires a return
|
||||
return '';
|
||||
})()`;
|
||||
}
|
||||
// It is hacky way to make this function will be compiled preferentially by less
|
||||
// resolve error: `ReferenceError: colorPalette is not defined`
|
||||
// https://github.com/ant-design/ant-motion/issues/44
|
||||
.bezierEasingMixin();
|
||||
|
|
@ -56,9 +56,7 @@ html {
|
|||
}
|
||||
|
||||
// IE10+ doesn't honor `<meta name="viewport">` in some cases.
|
||||
@at-root {
|
||||
@-ms-viewport { width: device-width; }
|
||||
}
|
||||
@-ms-viewport { width: device-width; }
|
||||
|
||||
// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
|
||||
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
|
||||
// LINK
|
||||
@link-color : @primary-color;
|
||||
@link-hover-color : @primary-5;
|
||||
@link-active-color : @primary-7;
|
||||
@link-hover-color : color(~`colorPalette("@{link-color}", 5)`);
|
||||
@link-active-color : color(~`colorPalette("@{link-color}", 7)`);
|
||||
@link-decoration : none;
|
||||
@link-hover-decoration : none;
|
||||
|
||||
|
@ -336,6 +336,7 @@
|
|||
@table-header-sort-bg: @background-color-base;
|
||||
@table-row-hover-bg: @primary-1;
|
||||
@table-selected-row-bg: #fafafa;
|
||||
@table-expanded-row-bg: #fbfbfb;
|
||||
@table-padding-vertical: 16px;
|
||||
@table-padding-horizontal: 16px;
|
||||
|
||||
|
@ -387,6 +388,8 @@
|
|||
@tabs-card-height: 40px;
|
||||
@tabs-card-active-color: @primary-color;
|
||||
@tabs-title-font-size: @font-size-base;
|
||||
@tabs-title-font-size-lg: @font-size-lg;
|
||||
@tabs-title-font-size-sm: @font-size-base;
|
||||
@tabs-ink-bar-bg-color: @primary-color;
|
||||
@tab-bar-margin: 0 0 16px 0;
|
||||
@tab-horizontal-margin: 0 32px 0 0;
|
||||
|
@ -420,6 +423,7 @@
|
|||
// ---
|
||||
@switch-height: 22px;
|
||||
@switch-sm-height: 16px;
|
||||
@switch-sm-checked-margin-left: -(@switch-sm-height - 3px);
|
||||
@switch-disabled-opacity: 0.4;
|
||||
@switch-color: @primary-color;
|
||||
|
||||
|
@ -428,6 +432,7 @@
|
|||
@pagination-item-size: 32px;
|
||||
@pagination-item-size-sm: 24px;
|
||||
@pagination-font-family: Arial;
|
||||
@pagination-font-weight-active: 500;
|
||||
|
||||
// Breadcrumb
|
||||
// ---
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
}
|
||||
|
||||
&-large &-nav-container {
|
||||
font-size: @font-size-lg;
|
||||
font-size: @tabs-title-font-size-lg;
|
||||
}
|
||||
|
||||
&-large &-tab {
|
||||
|
@ -215,7 +215,7 @@
|
|||
}
|
||||
|
||||
&-small &-nav-container {
|
||||
font-size: @font-size-base;
|
||||
font-size: @tabs-title-font-size-sm;
|
||||
}
|
||||
|
||||
&-small &-tab {
|
||||
|
|
|
@ -48,6 +48,11 @@ export default {
|
|||
sourceCode = style ? sourceCode + '\<style>' + style + '<\/style>' : sourceCode
|
||||
const usTitle = (us.split('#### ')[1] || '').split('\n')[0] || ''
|
||||
const cnTitle = (cn.split('#### ')[1] || '').split('\n')[0] || ''
|
||||
if (process.env.NODE_ENV !== 'production' && usTitle === '') {
|
||||
throw new Error(
|
||||
`not have usTitle`,
|
||||
)
|
||||
}
|
||||
const id = ['components', name.replace('-cn', ''), 'demo', ...usTitle.split(' ')].join('-').toLowerCase()
|
||||
if (this._store.store) {
|
||||
const { currentSubMenu } = this._store.store.getState()
|
||||
|
|
Loading…
Reference in New Issue