Skip to content

Commit

Permalink
feat(statistic): add Statistic component (#2397)
Browse files Browse the repository at this point in the history
* Merge branch 'docs/statistic' into feat/statistic

* feat(statistic): add new component for statistic

add new component for statistic

BREAKING CHANGE: add statistic

#2265

* perf(renamed icons for consistency): renamed icons for consistency

Renamed icons for consistency

* feat(statistic): add component tests and update examples

add component tests and update examples

* chore(submodules): submodules

* docs(statistic): add file description

* chore: update snapshot

* chore: fix ui feedback

* chore: update snapshot

* chore: update common

* chore: update common

---------

Co-authored-by: Uyarn <[email protected]>
  • Loading branch information
oljc and uyarn authored Nov 22, 2023
1 parent 7b312f6 commit ea70a50
Show file tree
Hide file tree
Showing 21 changed files with 1,717 additions and 1 deletion.
8 changes: 8 additions & 0 deletions site/site.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,14 @@ const docs = [
component: () => import('tdesign-vue/skeleton/skeleton.md'),
componentEn: () => import('tdesign-vue/skeleton/skeleton.en-US.md'),
},
{
title: 'Statistic 统计数值',
titleEn: 'Statistic',
name: 'statistic',
path: '/vue/components/statistic',
component: () => import('tdesign-vue/statistic/statistic.md'),
componentEn: () => import('tdesign-vue/statistic/statistic.en-US.md'),
},
{
title: 'Swiper 轮播框',
titleEn: 'Swiper',
Expand Down
1 change: 1 addition & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export * from './list';
export * from './loading';
export * from './progress';
export * from './skeleton';
export * from './statistic';
export * from './swiper';
export * from './table';
export * from './tag';
Expand Down
114 changes: 114 additions & 0 deletions src/statistic/__tests__/index.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { mount } from '@vue/test-utils';
import Statistic from '@/src/statistic/index.ts';

describe('Statistic', () => {
describe(':props', () => {
it('title', () => {
const wrapper = mount({
render() {
return <Statistic title="Total Assets" value={82.76} />;
},
});
expect(wrapper.find('.t-statistic-title').exists()).toBe(true);
expect(wrapper.find('.t-statistic-title').text()).toBe('Total Assets');
});

it('value', () => {
const wrapper = mount({
render() {
return <Statistic title="Total Assets" value={82.76} unit="%" trend="increase" />;
},
});
expect(wrapper.find('.t-statistic-content-value').exists()).toBe(true);
expect(wrapper.find('.t-statistic-content-value').text()).toBe('82.76');
});

it('unit', () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Total Sales',
value: 1000,
unit: 'pcs',
},
});

expect(wrapper.find('.t-statistic-content-unit').text()).toBe('pcs');
});

it('decimalPlaces', () => {
const wrapper = mount({
render() {
return <Statistic title="Total Assets" value={123.45678} decimalPlaces={3} />;
},
});
expect(wrapper.find('.t-statistic-content-value').exists()).toBe(true);
expect(wrapper.find('.t-statistic-content-value').text()).toBe('123.457');
});

it('prefix', () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Total Sales',
value: 1000,
prefix: '$',
},
});

expect(wrapper.find('.t-statistic-content-prefix').text()).toBe('$');
});

it('suffix', () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Total Sales',
value: 1000,
suffix: 'K',
},
});

expect(wrapper.find('.t-statistic-content-suffix').text()).toBe('K');
});

it('loading', async () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Downloads',
value: 1000,
loading: true,
},
});

expect(wrapper.find('.t-statistic-title').text()).toBe('Downloads');
expect(wrapper.find('.t-skeleton').exists()).toBe(true);
expect(wrapper.find('.t-skeleton__row').exists()).toBe(true);
});

it('trend="increase"', () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Total Sales',
value: 1000,
trend: 'increase',
},
});

const trendIconElement = wrapper.find('.t-icon.t-icon-arrow-triangle-up-filled');
expect(trendIconElement.exists()).toBe(true);
expect(trendIconElement.is('svg')).toBe(true);
});

it('trend="decrease"', () => {
const wrapper = mount(Statistic, {
propsData: {
title: 'Total Sales',
value: 1000,
trend: 'decrease',
},
});

const trendIconElement = wrapper.find('.t-icon.t-icon-arrow-triangle-down-filled');
expect(trendIconElement.exists()).toBe(true);
expect(trendIconElement.is('svg')).toBe(true);
});
});
});
32 changes: 32 additions & 0 deletions src/statistic/_example/animation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<t-space direction="vertical">
<t-space>
<t-button @click="start = true">Start</t-button>
<t-button @click="value = 98.12">Update value</t-button>
<t-button @click="$refs.refUp.start()">refs</t-button>
</t-space>
<t-statistic
ref="refUp"
title="Total Assets"
suffix="%"
:value="value"
:animation="{
valueFrom: 0,
duration: 2000,
}"
:decimal-places="2"
:animation-start="start"
/>
</t-space>
</template>

<script>
export default {
data() {
return {
start: false,
value: 56.32,
};
},
};
</script>
6 changes: 6 additions & 0 deletions src/statistic/_example/base.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<t-space :size="100">
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" />
<t-statistic title="Total Assets" :value="82.76" unit="USD" trend="increase" />
</t-space>
</template>
9 changes: 9 additions & 0 deletions src/statistic/_example/color.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<t-space>
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" color="black" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" color="blue" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" color="red" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" color="orange" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" color="green" />
</t-space>
</template>
55 changes: 55 additions & 0 deletions src/statistic/_example/combination.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<t-space :size="100" breakLine>
<t-space align="center">
<t-icon name="chart" class="icon" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" trendPlacement="right" />
</t-space>

<t-space align="center">
<t-statistic title="Total Assets" :value="52.18" unit="%" trend="decrease" />
<t-icon name="internet" class="icon" style="border-radius: 50%" />
</t-space>

<t-card title="Yesterday traffic" header-bordered hover-shadow>
<t-space :separator="separator">
<t-statistic title="Voice duration" :value="789" unit="minute" extra="the day before 9%" />
<t-statistic title="Total number of voice DAUs" :value="188" color="red">
<template #extra>
<t-space direction="vertical" :size="0">
<span>
the day before
<t-icon name="arrow-up" style="color: #d54941" />
9%
</span>
<span>
last week
<t-icon name="arrow-down" style="color: #2ba471" />
9%
</span>
</t-space>
</template>
</t-statistic>
<t-statistic title="Total Assets" :value="52.18" unit="%" trend="decrease" color="green" />
</t-space>
</t-card>
</t-space>
</template>

<script lang="jsx">
export default {
data() {
return {
separator: () => <t-divider layout="vertical" style="height:100%" />,
};
},
};
</script>
<style>
.icon {
font-size: 32px;
color: var(--td-brand-color);
background: var(--td-brand-color-light);
border-radius: var(--td-radius-medium);
padding: 12px;
}
</style>
16 changes: 16 additions & 0 deletions src/statistic/_example/loading.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<t-space direction="vertical">
<t-switch v-model="loading" size="large" />
<t-statistic title="Downloads" :value="123456" :loading="loading" />
</t-space>
</template>

<script>
export default {
data() {
return {
loading: true,
};
},
};
</script>
26 changes: 26 additions & 0 deletions src/statistic/_example/slot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<t-space :size="32">
<t-statistic title="Total Assets" :value="56.32" unit="%">
<template #prefix>
<control-platform-icon />
</template>
</t-statistic>
<t-statistic title="Total Assets" :value="176059" prefix="$" unit="%" trend="increase" />

<t-statistic title="Total Assets" :value="62.58">
<template #suffix>
<arrow-triangle-down-filled-icon style="color: #ee4d38" />
</template>
</t-statistic>
</t-space>
</template>
<script>
import { ControlPlatformIcon, ArrowTriangleDownFilledIcon } from 'tdesign-icons-vue';
export default {
components: {
ArrowTriangleDownFilledIcon,
ControlPlatformIcon,
},
};
</script>
7 changes: 7 additions & 0 deletions src/statistic/_example/trend.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<t-space :size="100">
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="increase" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="decrease" />
<t-statistic title="Total Assets" :value="82.76" unit="%" trend="decrease" trendPlacement="right" />
</t-space>
</template>
12 changes: 12 additions & 0 deletions src/statistic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import _Statistic from './statistic';
import withInstall from '../utils/withInstall';
import { TdStatisticProps } from './type';

import './style';

export * from './type';
export type StatisticProps = TdStatisticProps;

export const Statistic = withInstall(_Statistic);

export default Statistic;
81 changes: 81 additions & 0 deletions src/statistic/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* eslint-disable */

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TdStatisticProps } from './type';
import { PropType } from 'vue';

export default {
/** 动画效果控制,`duration` 指动画的过渡时间`单位:毫秒`,`valueFrom` 指动画的起始数值。`{ duration, valueFrom }` */
animation: {
type: Object as PropType<TdStatisticProps['animation']>,
},
/** 是否开始动画 */
animationStart: Boolean,
/** 颜色风格,依次为 TDesign 风格的黑色、蓝色、红色、橙色、绿色。也可以为任何 [CSS color](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) 支持的 RGB 等值 */
color: {
type: String as PropType<TdStatisticProps['color']>,
validator(val: TdStatisticProps['color']): boolean {
if (!val) return true;
return ['black', 'blue', 'red', 'orange', 'green'].includes(val);
},
},
/** 小数保留位数 */
decimalPlaces: {
type: Number,
},
/** 额外的显示内容 */
extra: {
type: [String, Function] as PropType<TdStatisticProps['extra']>,
},
/** 格式化数值显示值 */
format: {
type: Function as PropType<TdStatisticProps['format']>,
},
/** 是否加载中 */
loading: Boolean,
/** 前缀内容,展示优先级高于 trend */
prefix: {
type: [String, Function] as PropType<TdStatisticProps['prefix']>,
},
/** 默认展示进位分隔符,可以自定义为其他内容,`separator = ''` 设置为空字符串/null/undefined 时隐藏分隔符 */
separator: {
type: String,
default: ',',
},
/** 后缀内容,展示优先级高于 trend */
suffix: {
type: [String, Function] as PropType<TdStatisticProps['suffix']>,
},
/** 数值显示的标题 */
title: {
type: [String, Function] as PropType<TdStatisticProps['title']>,
},
/** 趋势 */
trend: {
type: String as PropType<TdStatisticProps['trend']>,
validator(val: TdStatisticProps['trend']): boolean {
if (!val) return true;
return ['increase', 'decrease'].includes(val);
},
},
/** 趋势展示位置 */
trendPlacement: {
type: String as PropType<TdStatisticProps['trendPlacement']>,
default: 'left' as TdStatisticProps['trendPlacement'],
validator(val: TdStatisticProps['trendPlacement']): boolean {
if (!val) return true;
return ['left', 'right'].includes(val);
},
},
/** 单位内容 */
unit: {
type: [String, Function] as PropType<TdStatisticProps['unit']>,
},
/** 数值显示的值 */
value: {
type: Number,
},
};
Loading

0 comments on commit ea70a50

Please sign in to comment.