cr pxxx to sxxx and tree

This commit is contained in:
tanjinzhou 2019-09-18 20:03:13 +08:00
parent 4ce99b91e1
commit c015c8d34c
32 changed files with 380 additions and 82 deletions

View File

@ -133,6 +133,7 @@ const getComponentFromProp = (instance, prop, options = instance, execute = true
const componentOptions = instance.componentOptions || {};
(componentOptions.children || []).forEach(child => {
if (child.data && child.data.slot === prop) {
delete child.data.slot;
if (child.tag === 'template') {
slotsProp.push(child.children);
} else {

View File

@ -1,6 +1,5 @@
import { Circle as VCCircle } from '../vc-progress';
import { validProgress } from './utils';
import { ProgressProps } from './progress';
const statusColorMap = {
normal: '#108ee9',

View File

@ -1,5 +1,4 @@
import { validProgress } from './utils';
import { ProgressProps } from './progress';
const Line = {
functional: true,

View File

@ -11,9 +11,7 @@ export default {
prop: 'value',
},
props: {
prefixCls: {
type: String,
},
prefixCls: PropTypes.string,
defaultValue: PropTypes.any,
value: PropTypes.any,
size: {
@ -103,7 +101,6 @@ export default {
prefixCls={prefixCls}
disabled={props.disabled}
value={option}
onChange={this.onRadioChange}
checked={this.stateValue === option}
>
{option}
@ -116,7 +113,6 @@ export default {
prefixCls={prefixCls}
disabled={option.disabled || props.disabled}
value={option.value}
onChange={this.onRadioChange}
checked={this.stateValue === option.value}
>
{option.label}

View File

@ -12,9 +12,7 @@ export default {
prop: 'checked',
},
props: {
prefixCls: {
type: String,
},
prefixCls: PropTypes.string,
defaultChecked: Boolean,
checked: { type: Boolean, default: undefined },
disabled: Boolean,
@ -41,6 +39,12 @@ export default {
blur() {
this.$refs.vcCheckbox.blur();
},
onChange(e) {
this.$emit('change', e);
if (this.radioGroupContext && this.radioGroupContext.onRadioChange) {
this.radioGroupContext.onRadioChange(e);
}
},
},
render() {
@ -60,7 +64,7 @@ export default {
if (radioGroup) {
radioProps.props.name = radioGroup.name;
radioProps.on.change = radioGroup.onRadioChange;
radioProps.on.change = this.onChange;
radioProps.props.checked = props.value === radioGroup.stateValue;
radioProps.props.disabled = props.disabled || radioGroup.disabled;
} else {

View File

@ -1,4 +1,5 @@
import Radio from './Radio';
import PropTypes from '../_util/vue-types';
import { getOptionProps } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
@ -6,9 +7,6 @@ export default {
name: 'ARadioButton',
props: {
...Radio.props,
prefixCls: {
type: String,
},
},
inject: {
radioGroupContext: { default: undefined },

View File

@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
import Radio from '../Radio';
import RadioGroup from '../Group';
import RadioButton from '../radioButton';
describe('Radio', () => {
function createRadioGroup(props, listeners = {}) {
@ -50,10 +51,16 @@ describe('Radio', () => {
},
});
wrapper.trigger('mouseenter');
wrapper
.findAll('div')
.at(0)
.trigger('mouseenter');
expect(onMouseEnter).toHaveBeenCalled();
wrapper.trigger('mouseleave');
wrapper
.findAll('div')
.at(0)
.trigger('mouseleave');
expect(onMouseLeave).toHaveBeenCalled();
});
@ -89,6 +96,80 @@ describe('Radio', () => {
});
});
it('both of radio and radioGroup will trigger onchange event when they exists', async () => {
const onChange = jest.fn();
const onChangeRadioGroup = jest.fn();
const wrapper = mount(
{
props: ['value'],
render() {
const groupProps = {};
if (this.value !== undefined) {
groupProps.value = this.value;
}
return (
<RadioGroup ref="radioGroup" {...groupProps} onChange={onChangeRadioGroup}>
<Radio value="A" onChange={onChange}>
A
</Radio>
<Radio value="B" onChange={onChange}>
B
</Radio>
<Radio value="C" onChange={onChange}>
C
</Radio>
</RadioGroup>
);
},
},
{ sync: false },
);
const radios = wrapper.findAll('input');
// uncontrolled component
wrapper.vm.$refs.radioGroup.stateValue = 'B';
radios.at(0).trigger('change');
expect(onChange.mock.calls.length).toBe(1);
expect(onChangeRadioGroup.mock.calls.length).toBe(1);
// controlled component
wrapper.setProps({ value: 'A' });
radios.at(1).trigger('change');
expect(onChange.mock.calls.length).toBe(2);
});
it('Trigger onChange when both of radioButton and radioGroup exists', () => {
const onChange = jest.fn();
const props = {};
const wrapper = mount(
createRadioGroup(props, {
change: onChange,
}),
{ sync: false },
);
const radios = wrapper.findAll('input');
// uncontrolled component
wrapper.vm.$refs.radioGroup.stateValue = 'B';
radios.at(0).trigger('change');
expect(onChange.mock.calls.length).toBe(1);
// controlled component
wrapper.setProps({ value: 'A' });
radios.at(1).trigger('change');
expect(onChange.mock.calls.length).toBe(2);
});
// it('should only trigger once when in group with options', () => {
// const onChange = jest.fn();
// const options = [{ label: 'Bamboo', value: 'Bamboo' }];
// const wrapper = mount(<RadioGroup options={options} onChange={onChange} />);
// wrapper.find('input').trigger('change');
// expect(onChange).toHaveBeenCalledTimes(1);
// });
// it('won\'t fire change events when value not changes', async () => {
// const onChange = jest.fn()

View File

@ -28,12 +28,12 @@ describe('Radio', () => {
{ sync: false },
);
await asyncExpect(() => {
wrapper.trigger('mouseenter');
wrapper.find('label').trigger('mouseenter');
});
await asyncExpect(() => {
expect(onMouseEnter).toHaveBeenCalled();
});
wrapper.trigger('mouseleave');
wrapper.find('label').trigger('mouseleave');
await asyncExpect(() => {
expect(onMouseLeave).toHaveBeenCalled();
});

View File

@ -40,12 +40,7 @@ const Rate = {
characterRender(node, { index }) {
const { tooltips } = this.$props;
if (!tooltips) return node;
const tooltipsProps = {
props: {
title: tooltips[index],
},
};
return <Tooltip {...tooltipsProps}>{node}</Tooltip>;
return <Tooltip title={tooltips[index]}>{node}</Tooltip>;
},
},
render() {

View File

@ -1,4 +1,4 @@
import warning from 'warning';
import warning from '../_util/warning';
import omit from 'omit.js';
import PropTypes from '../_util/vue-types';
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
@ -96,7 +96,6 @@ const Select = {
name: 'ASelect',
props: {
...SelectProps,
prefixCls: PropTypes.string,
showSearch: PropTypes.bool.def(false),
transitionName: PropTypes.string.def('slide-up'),
choiceTransitionName: PropTypes.string.def('zoom'),

View File

@ -1,5 +1,4 @@
import PropTypes from '../_util/vue-types';
import { initDefaultProps } from '../_util/props-util';
const skeletonTitleProps = {
prefixCls: PropTypes.string,

View File

@ -16,8 +16,6 @@ const md = {
- 网络较慢需要长时间等待加载处理的情况下
- 图文信息内容较多的列表/卡片中
- 只适合用在第一次加载数据的场景
- 可以被 Spin 完全代替但是在可用的场景下可以比 Spin 提供更好的视觉效果和用户体验
## 代码演示`,
us: `# Skeleton
@ -27,8 +25,6 @@ const md = {
- When resource needs long time to load, like low network speed.
- The component contains much information. Such as List or Card.
- Only works when loading data at first time.
- Could be replaced by Spin in all situation, but provide better user experience then spin if it works.
## Examples
`,
};
@ -38,12 +34,12 @@ export default {
type: 'Feedback',
title: 'Skeleton',
cols: 1,
render () {
render() {
return (
<div>
<md cn={md.cn} us={md.us}/>
<br/>
<Basic/>
<md cn={md.cn} us={md.us} />
<br />
<Basic />
<br />
<Complex />
<br />
@ -52,12 +48,12 @@ export default {
<Children />
<br />
<List />
<br/>
<br />
<api>
<template slot='cn'>
<CN/>
<template slot="cn">
<CN />
</template>
<US/>
<US />
</api>
</div>
);

View File

@ -3,11 +3,11 @@
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| autoFocus | get focus when component mounted | boolean | false |
| defaultValue | The default value of slider. When `range` is `false`, use `number`, otherwise, use `[number, number]` | number\|number\[] | 0 or [0, 0] |
| defaultValue | The default value of slider. When `range` is `false`, use `number`, otherwise, use `[number, number]` | number\|number\[] | 0 or \[0, 0] |
| disabled | If true, the slider will not be interactable. | boolean | false |
| dots | Whether the thumb can drag over tick only. | boolean | false |
| included | Make effect when `marks` not null`true` means containment and `false` means coordinative | boolean | true |
| marks | Tick mark of Slider, type of key must be `number`, and must in closed interval [min, max] each mark can declare its own style. | object | { number: string\|VNode } or { number: { style: object, label: string\|VNode } } or { number: () => VNode } |
| marks | Tick mark of Slider, type of key must be `number`, and must in closed interval \[min, max], each mark can declare its own style. | object | { number: string\|VNode } or { number: { style: object, label: string\|VNode } } or { number: () => VNode } |
| max | The maximum value the slider can slide to | number | 100 |
| min | The minimum value the slider can slide to. | number | 0 |
| range | dual thumb mode | boolean | false |

View File

@ -6,6 +6,7 @@ import VcRange from '../vc-slider/src/Range';
import VcHandle from '../vc-slider/src/Handle';
import Tooltip from '../tooltip';
import Base from '../base';
import { ConfigConsumerProps } from '../config-provider';
// export interface SliderMarks {
// [key]: React.ReactNode | {
@ -43,10 +44,11 @@ const Slider = {
event: 'change',
},
mixins: [BaseMixin],
inject: {
configProvider: { default: () => ConfigConsumerProps },
},
props: {
...SliderProps(),
prefixCls: PropTypes.string.def('ant-slider'),
tooltipPrefixCls: PropTypes.string.def('ant-tooltip'),
tipFormatter: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).def(value =>
value.toString(),
),
@ -65,8 +67,8 @@ const Slider = {
},
}));
},
handleWithTooltip({ value, dragging, index, directives, on, ...restProps }) {
const { tooltipPrefixCls, tipFormatter, tooltipVisible } = this.$props;
handleWithTooltip(tooltipPrefixCls, { value, dragging, index, directives, on, ...restProps }) {
const { tipFormatter, tooltipVisible } = this.$props;
const { visibles } = this;
const isTipFormatter = tipFormatter ? visibles[index] || dragging : false;
const visible = tooltipVisible || (tooltipVisible === undefined && isTipFormatter);
@ -106,12 +108,22 @@ const Slider = {
},
},
render() {
const { range, ...restProps } = getOptionProps(this);
const {
range,
prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls,
...restProps
} = getOptionProps(this);
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('skeleton', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('skeleton', customizeTooltipPrefixCls);
if (range) {
const vcRangeProps = {
props: {
...restProps,
handle: this.handleWithTooltip,
prefixCls,
tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, info),
},
ref: 'sliderRef',
on: this.$listeners,
@ -121,7 +133,9 @@ const Slider = {
const vcSliderProps = {
props: {
...restProps,
handle: this.handleWithTooltip,
prefixCls,
tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, info),
},
ref: 'sliderRef',
on: this.$listeners,

View File

@ -3,11 +3,11 @@
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| autoFocus | 自动获取焦点 | boolean | false |
| defaultValue | 设置初始取值。当 `range``false` 时,使用 `number`,否则用 `[number, number]` | number\|number\[] | 0 or [0, 0] |
| defaultValue | 设置初始取值。当 `range``false` 时,使用 `number`,否则用 `[number, number]` | number\|number\[] | 0 or \[0, 0] |
| disabled | 值为 `true` 时,滑块为禁用状态 | boolean | false |
| dots | 是否只能拖拽到刻度上 | boolean | false |
| included | `marks` 不为空对象时有效,值为 true 时表示值为包含关系false 表示并列 | boolean | true |
| marks | 刻度标记key 的类型必须为 `number` 且取值在闭区间 [min, max] 内,每个标签可以单独设置样式 | object | { number: string\|VNode } or { number: { style: object, label: string\|VNode } } or { number: () => VNode } |
| marks | 刻度标记key 的类型必须为 `number` 且取值在闭区间 \[min, max] 内,每个标签可以单独设置样式 | object | { number: string\|VNode } or { number: { style: object, label: string\|VNode } } or { number: () => VNode } |
| max | 最大值 | number | 100 |
| min | 最小值 | number | 0 |
| range | 双滑块模式 | boolean | false |

View File

@ -51,10 +51,11 @@ export default {
},
data() {
const { spinning, delay } = this;
const shouldBeDelayed = shouldDelay(spinning, delay);
this.originalUpdateSpinning = this.updateSpinning;
this.debouncifyUpdateSpinning(this.$props);
return {
sSpinning: spinning && !shouldDelay(spinning, delay),
sSpinning: spinning && !shouldBeDelayed,
};
},
mounted() {

View File

@ -0,0 +1,69 @@
import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
import Spin from '..';
describe('delay spinning', () => {
it("should render with delay when it's mounted with spinning=true and delay", async () => {
const props = {
propsData: {
delay: 500,
spinning: true,
},
sync: false,
};
const wrapper = mount(Spin, props);
await asyncExpect(() => {
expect(
wrapper
.find('.ant-spin')
.classes()
.includes('ant-spin-spinning'),
).toEqual(false);
});
});
it('should render when delay is init set', async () => {
const props = {
propsData: {
delay: 100,
spinning: true,
},
sync: false,
};
const wrapper = mount(Spin, props);
expect(
wrapper
.findAll('.ant-spin')
.at(0)
.classes()
.includes('ant-spin-spinning'),
).toEqual(false);
// use await not jest.runAllTimers()
// because of https://github.com/facebook/jest/issues/3465
await new Promise(resolve => setTimeout(resolve, 500));
expect(
wrapper
.findAll('.ant-spin')
.at(0)
.classes()
.includes('ant-spin-spinning'),
).toEqual(true);
});
it('should cancel debounce function when unmount', async () => {
const props = {
propsData: {
delay: 100,
spinning: true,
},
sync: false,
};
const wrapper = mount(Spin, props);
const spy = jest.spyOn(wrapper.vm.updateSpinning, 'cancel');
expect(wrapper.vm.updateSpinning.cancel).toEqual(expect.any(Function));
expect(spy).not.toHaveBeenCalled();
});
});

View File

@ -17,24 +17,16 @@ export default {
format: 'HH:mm:ss',
}),
data() {
return {
uniKey: 0,
};
created() {
this.countdownId = undefined;
},
countdownId: undefined,
mounted() {
this.$nextTick(() => {
this.syncTimer();
});
this.syncTimer();
},
updated() {
this.$nextTick(() => {
this.syncTimer();
});
this.syncTimer();
},
beforeDestroy() {
@ -53,11 +45,9 @@ export default {
},
startTimer() {
if (this.countdownId) {
return;
}
if (this.countdownId) return;
this.countdownId = window.setInterval(() => {
this.uniKey++;
this.$refs.statistic.$forceUpdate();
}, REFRESH_INTERVAL);
},
@ -74,7 +64,7 @@ export default {
}
},
formatCountdown(value, config) {
formatCountdown({ value, config }) {
const { format } = this.$props;
return formatCountdown(value, { ...config, format });
},
@ -91,13 +81,14 @@ export default {
render() {
return (
<Statistic
key={this.uniKey}
ref="statistic"
{...{
props: {
...this.$props,
valueRender: this.valueRenderHtml,
formatter: this.formatCountdown,
},
on: this.$listeners,
}}
/>
);

View File

@ -12,12 +12,11 @@ export default {
groupSeparator = '',
prefixCls,
} = context.props;
let valueNode;
if (typeof formatter === 'function') {
// Customize formatter
valueNode = formatter(value);
valueNode = formatter({ value, h });
} else {
// Internal formatter
const val = String(value);

View File

@ -8,7 +8,7 @@ export const StatisticProps = {
decimalSeparator: PropTypes.string,
groupSeparator: PropTypes.string,
format: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
valueStyle: PropTypes.any,
valueRender: PropTypes.any,
formatter: PropTypes.any,
@ -21,7 +21,6 @@ export const StatisticProps = {
export default {
name: 'AStatistic',
props: initDefaultProps(StatisticProps, {
prefixCls: 'ant-statistic',
decimalSeparator: '.',
groupSeparator: ',',
}),
@ -37,9 +36,9 @@ export default {
const title = getComponentFromProp(this, 'title');
let prefix = getComponentFromProp(this, 'prefix');
let suffix = getComponentFromProp(this, 'suffix');
const formatter = getComponentFromProp(this, 'formatter');
const formatter = getComponentFromProp(this, 'formatter', {}, false);
let valueNode = (
<StatisticNumber {...{ props: this.$props }} value={value} formatter={formatter} />
<StatisticNumber {...{ props: { ...this.$props, prefixCls, value, formatter } }} />
);
if (valueRender) {
valueNode = valueRender(valueNode);

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Statistic support negetive number 1`] = `
<div class="ant-statistic">
<div class="ant-statistic-title">Account Balance (CNY)</div>
<div class="ant-statistic-content"><span class="ant-statistic-content-value"><span class="ant-statistic-content-value-int">-112,893</span><span class="ant-statistic-content-value-decimal">.12</span></span></div>
</div>
`;

View File

@ -0,0 +1,107 @@
import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
import MockDate from 'mockdate';
import moment from 'moment';
import Statistic from '..';
describe('Statistic', () => {
beforeAll(() => {
MockDate.set(moment('2018-11-28 00:00:00'));
});
afterAll(() => {
MockDate.reset();
});
it('customize formatter', () => {
const formatter = jest.fn(() => 93);
const props = {
propsData: {
value: 1128,
formatter,
},
};
const wrapper = mount(Statistic, props);
expect(formatter).toBeCalledWith(expect.objectContaining({ value: 1128 }));
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('93');
});
it('groupSeparator', () => {
const props = {
propsData: {
value: 1128,
groupSeparator: '__TEST__',
},
};
const wrapper = mount(Statistic, props);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('1__TEST__128');
});
it('not a number', () => {
const props = {
propsData: {
value: 'bamboo',
},
};
const wrapper = mount(Statistic, props);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('bamboo');
});
it('support negetive number', () => {
const props = {
propsData: {
title: 'Account Balance (CNY)',
value: -112893.12345,
precision: 2,
},
};
const wrapper = mount(Statistic, props);
expect(wrapper.html()).toMatchSnapshot();
});
describe('Countdown', () => {
it('render correctly', () => {
const now = moment()
.add(2, 'd')
.add(11, 'h')
.add(28, 'm')
.add(9, 's')
.add(3, 'ms');
[
['H:m:s', '59:28:9'],
['HH:mm:ss', '59:28:09'],
['HH:mm:ss:SSS', '59:28:09:003'],
['DD-HH:mm:ss', '02-11:28:09'],
].forEach(([format, value]) => {
const props = {
propsData: {
format,
value: now,
},
};
const wrapper = mount(Statistic.Countdown, props);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual(value);
});
});
it('time going', async () => {
const now = Date.now() + 1000;
const props = {
propsData: {
value: now,
},
};
const wrapper = mount(Statistic.Countdown, props);
// setInterval should work
const instance = wrapper.vm;
expect(instance.countdownId).not.toBe(undefined);
// await delay(50);
// wrapper.unmount();
// expect(instance.countdownId).toBe(undefined);
});
});
});

View File

@ -5,13 +5,14 @@
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| decimalSeparator | decimal separator | string | . |
| formatter | customize value display logic | v-slot \|(h) => VNode | - |
| formatter | customize value display logic | v-slot \|({h, value}) => VNode | - |
| groupSeparator | group separator | string | , |
| precision | precision of input value | number | - |
| prefix | prefix node of value | string \| v-slot | - |
| suffix | suffix node of value | string \| v-slot | - |
| title | Display title | string \| v-slot | - |
| value | Display value | string \| number | - |
| valueStyle | Set value css style | style | - |
### Statistic.Countdown
@ -23,6 +24,7 @@
| suffix | suffix node of value | string \| v-slot | - |
| title | Display title | string \| v-slot | - |
| value | Set target countdown time | number \| moment | - |
| valueStyle | Set value css style | style | - |
#### Statistic.Countdown Events
| Events Name | Description | Arguments |

View File

@ -1,9 +1,11 @@
import Statistic from './Statistic';
import Countdown from './Countdown';
import Base from '../base';
Statistic.Countdown = Countdown;
/* istanbul ignore next */
Statistic.install = function(Vue) {
Vue.use(Base);
Vue.component(Statistic.name, Statistic);
Vue.component(Statistic.Countdown.name, Statistic.Countdown);
};

View File

@ -5,13 +5,14 @@
| 参数 | 说明 | 类型 | 默认值 |
| -------- | ----------- | ---- | ------- |
| decimalSeparator | 设置小数点 | string | . |
| formatter | 自定义数值展示 | v-slot \| (h) => VNode | - |
| formatter | 自定义数值展示 | v-slot \| ({h, value}) => VNode | - |
| groupSeparator | 设置千分位标识符 | string | , |
| precision | 数值精度 | number | - |
| prefix | 设置数值的前缀 | string \| v-slot | - |
| suffix | 设置数值的后缀 | string \| v-slot | - |
| title | 数值的标题 | string \| v-slot | - |
| value | 数值内容 | string \| number | - |
| valueStyle | 设置数值的样式 | style | - |
### Statistic.Countdown
@ -22,6 +23,7 @@
| suffix | 设置数值的后缀 | string \| v-slot | - |
| title | 数值的标题 | string \| v-slot | - |
| value | 数值内容 | number \| moment | - |
| valueStyle | 设置数值的样式 | style | - |
#### Statistic.Countdown事件
| 事件名称 | 说明 | 回调参数 |

View File

@ -141,7 +141,6 @@ export default {
const switcherOriginCls = getClass(switcherIcon[0]);
return cloneElement(switcherIcon, {
class: {
...switcherOriginCls,
[switcherCls]: true,
},
});

View File

@ -16,7 +16,7 @@ You can customize icons for different nodes.
defaultExpandAll
:defaultSelectedKeys="['0-0-0']"
>
<a-icon type="down" slot="switcherIcon" />
<a-icon type="down" slot="switcherIcon" class="test" />
<a-icon slot="smile" type="smile-o" />
<a-icon slot="meh" type="smile-o" />
<template slot="custom" slot-scope="{selected}">

View File

@ -24,7 +24,7 @@
| multiple | Allows selecting multiple treeNodes | boolean | false |
| selectedKeys(.sync) | (Controlled) Specifies the keys of the selected treeNodes | string\[] \| number\[] | - |
| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to `true` | boolean | false |
| switcherIcon | customize collapse/expand icon of tree node | slot(vnode) | - |
| switcherIcon | customize collapse/expand icon of tree node | slot | - |
| showLine | Shows a connecting line | boolean | false |
### Events

View File

@ -24,7 +24,7 @@
| multiple | 支持点选多个节点(节点本身) | boolean | false |
| selectedKeys(.sync) | (受控)设置选中的树节点 | string\[] \| number\[] | - |
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true需要自行定义图标相关样式 | boolean | false |
| switcherIcon | 自定义树节点的展开/折叠图标 | slot(vnode) | - |
| switcherIcon | 自定义树节点的展开/折叠图标 | slot | - |
| showLine | 是否展示连接线 | boolean | false |

2
types/rate.d.ts vendored
View File

@ -60,6 +60,8 @@ export declare class Rate extends AntdComponent {
*/
value: number;
tooltips: Array<string>;
/**
* remove focus
*/

View File

@ -0,0 +1,34 @@
// Project: https://github.com/vueComponent/ant-design-vue
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from '../component';
import { VNode } from 'vue';
export declare class AStatisticCountdown extends AntdComponent {
format: string;
/**
* prefix node of value
* @type string | VNode
*/
prefix: string | VNode;
/**
* suffix node of value
* @type string | VNode
*/
suffix: string | VNode;
/**
* Display title
* @type string | VNode
*/
title: string | VNode;
/**
* Display value
* @type string or number
*/
value: string | number;
valueStyle: object;
}

View File

@ -2,10 +2,12 @@
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from './component';
import { AntdComponent } from '../component';
import { VNode } from 'vue';
import AStatisticCountdown from './statistic-countdown';
export declare class Statistic extends AntdComponent {
static AStatisticCountdown: typeof AStatisticCountdown;
/**
* decimal separator
* @default '.'