From ecba505e95835ca96c705488499c7d4603db44fb Mon Sep 17 00:00:00 2001 From: James <72028410+James-9696@users.noreply.github.com> Date: Sat, 30 Mar 2024 10:04:06 +0800 Subject: [PATCH] feat(statistic): statistic component (#1491) * fix: add new component statistic * fix: add statistic renderless * feat: add statistic theme * feat: add statistic component * fix: update review * fix: update review * fix: update review --- examples/sites/demos/apis/statistic.js | 144 ++++++++++++++++++ .../statistic/basic-usage-composition-api.vue | 26 ++++ .../pc/app/statistic/basic-usage.spec.ts | 20 +++ .../demos/pc/app/statistic/basic-usage.vue | 38 +++++ .../statistic-slot-composition-api.vue | 39 +++++ .../pc/app/statistic/statistic-slot.spec.ts | 13 ++ .../demos/pc/app/statistic/statistic-slot.vue | 51 +++++++ .../statistic-style-composition-api.vue | 29 ++++ .../pc/app/statistic/statistic-style.spec.ts | 7 + .../pc/app/statistic/statistic-style.vue | 41 +++++ .../pc/app/statistic/webdoc/statistic.cn.md | 7 + .../pc/app/statistic/webdoc/statistic.en.md | 7 + .../pc/app/statistic/webdoc/statistic.js | 46 ++++++ examples/sites/demos/pc/menus.js | 3 +- examples/sites/demos/saas/menus.js | 3 +- packages/modules.json | 13 ++ packages/renderless/src/statistic/index.ts | 22 +++ packages/renderless/src/statistic/vue.ts | 21 +++ packages/renderless/types/index.ts | 1 + packages/renderless/types/statistic.type.ts | 20 +++ packages/theme/src/statistic/index.less | 48 ++++++ packages/theme/src/statistic/smb-theme.js | 6 + packages/theme/src/statistic/vars.less | 28 ++++ .../statistic/__tests__/statistic.test.tsx | 3 + packages/vue/src/statistic/index.ts | 35 +++++ packages/vue/src/statistic/package.json | 26 ++++ packages/vue/src/statistic/src/index.ts | 44 ++++++ packages/vue/src/statistic/src/pc.vue | 51 +++++++ 28 files changed, 790 insertions(+), 2 deletions(-) create mode 100644 examples/sites/demos/apis/statistic.js create mode 100644 examples/sites/demos/pc/app/statistic/basic-usage-composition-api.vue create mode 100644 examples/sites/demos/pc/app/statistic/basic-usage.spec.ts create mode 100644 examples/sites/demos/pc/app/statistic/basic-usage.vue create mode 100644 examples/sites/demos/pc/app/statistic/statistic-slot-composition-api.vue create mode 100644 examples/sites/demos/pc/app/statistic/statistic-slot.spec.ts create mode 100644 examples/sites/demos/pc/app/statistic/statistic-slot.vue create mode 100644 examples/sites/demos/pc/app/statistic/statistic-style-composition-api.vue create mode 100644 examples/sites/demos/pc/app/statistic/statistic-style.spec.ts create mode 100644 examples/sites/demos/pc/app/statistic/statistic-style.vue create mode 100644 examples/sites/demos/pc/app/statistic/webdoc/statistic.cn.md create mode 100644 examples/sites/demos/pc/app/statistic/webdoc/statistic.en.md create mode 100644 examples/sites/demos/pc/app/statistic/webdoc/statistic.js create mode 100644 packages/renderless/src/statistic/index.ts create mode 100644 packages/renderless/src/statistic/vue.ts create mode 100644 packages/renderless/types/statistic.type.ts create mode 100644 packages/theme/src/statistic/index.less create mode 100644 packages/theme/src/statistic/smb-theme.js create mode 100644 packages/theme/src/statistic/vars.less create mode 100644 packages/vue/src/statistic/__tests__/statistic.test.tsx create mode 100644 packages/vue/src/statistic/index.ts create mode 100644 packages/vue/src/statistic/package.json create mode 100644 packages/vue/src/statistic/src/index.ts create mode 100644 packages/vue/src/statistic/src/pc.vue diff --git a/examples/sites/demos/apis/statistic.js b/examples/sites/demos/apis/statistic.js new file mode 100644 index 000000000..587313f22 --- /dev/null +++ b/examples/sites/demos/apis/statistic.js @@ -0,0 +1,144 @@ +export default { + mode: ['pc'], + apis: [ + { + name: 'statistic', + type: 'component', + props: [ + { + name: 'value', + type: 'number', + defaultValue: '0', + desc: { + 'zh-CN': '数字显示内容', + 'en-US': 'Digital display content' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'precision', + type: 'number', + defaultValue: '0', + desc: { + 'zh-CN': '精度值', + 'en-US': 'Take precision value' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'title', + type: 'string | array', + defaultValue: '', + desc: { + 'zh-CN': '设置数字内容标题', + 'en-US': 'Set digital content titles' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'group-separator', + type: 'string', + defaultValue: ',', + desc: { + 'zh-CN': '设置千分位标志符', + 'en-US': 'Set Millennial Flag' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'prefix', + type: 'string', + defaultValue: '', + desc: { + 'zh-CN': '设置数字内容前缀', + 'en-US': 'Set numerical content prefix' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'suffix', + type: 'string', + defaultValue: '', + desc: { + 'zh-CN': '设置数字内容后缀', + 'en-US': 'Set numeric content suffix' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'formatter', + type: '(value) => {}', + defaultValue: '', + desc: { + 'zh-CN': '设置自定义数字格式化', + 'en-US': 'Set custom number formatting' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + }, + { + name: 'value-style', + type: 'string | object | array', + defaultValue: '', + desc: { + 'zh-CN': '设置数字样式', + 'en-US': 'Set Number Style' + }, + mode: ['pc'], + pcDemo: 'basic-usage', + mfDemo: '' + } + ], + events: [], + methods: [], + slots: [ + { + name: 'prefix', + type: '', + defaultValue: '', + desc: { + 'zh-CN': '数字内容前置插槽', + 'en-US': 'Digital content front slot' + }, + mode: ['pc'], + mfDemo: '' + }, + { + name: 'suffix', + type: '', + defaultValue: '', + desc: { + 'zh-CN': '数字内容后置插槽', + 'en-US': 'Digital content rear slot' + }, + mode: ['pc'], + mfDemo: '' + }, + { + name: 'title', + type: '', + defaultValue: '', + desc: { + 'zh-CN': '数字内容标题插槽', + 'en-US': 'Digital content title slot' + }, + mode: ['pc'], + mfDemo: '' + } + ] + } + ] +} diff --git a/examples/sites/demos/pc/app/statistic/basic-usage-composition-api.vue b/examples/sites/demos/pc/app/statistic/basic-usage-composition-api.vue new file mode 100644 index 000000000..782bdd2fc --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/basic-usage-composition-api.vue @@ -0,0 +1,26 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/basic-usage.spec.ts b/examples/sites/demos/pc/app/statistic/basic-usage.spec.ts new file mode 100644 index 000000000..2498e0328 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/basic-usage.spec.ts @@ -0,0 +1,20 @@ +import { test, expect } from '@playwright/test' + +test('基本用法', async ({ page }) => { + page.on('pageerror', (exception) => expect(exception).toBeNull()) + await page.goto('statistic#basic-usage') + await page + .locator('div') + .filter({ hasText: /123\/100$/ }) + .first() + .click() + await page + .locator('div') + .filter({ hasText: /^基本用法$/ }) + .first() + .click() + await page + .locator('div') + .filter({ hasText: /^306,526\.23$/ }) + .click() +}) diff --git a/examples/sites/demos/pc/app/statistic/basic-usage.vue b/examples/sites/demos/pc/app/statistic/basic-usage.vue new file mode 100644 index 000000000..43f2975dc --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/basic-usage.vue @@ -0,0 +1,38 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/statistic-slot-composition-api.vue b/examples/sites/demos/pc/app/statistic/statistic-slot-composition-api.vue new file mode 100644 index 000000000..cc6b90ea4 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-slot-composition-api.vue @@ -0,0 +1,39 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/statistic-slot.spec.ts b/examples/sites/demos/pc/app/statistic/statistic-slot.spec.ts new file mode 100644 index 000000000..d6179bc93 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-slot.spec.ts @@ -0,0 +1,13 @@ +import { test, expect } from '@playwright/test' + +test('插槽用法', async ({ page }) => { + page.on('pageerror', (exception) => expect(exception).toBeNull()) + await page.goto('statistic#statistic-slot') + await page.locator('div').filter({ hasText: /^10,010,258$/ }) + await page + .locator('div') + .filter({ hasText: /^306,526\.23$/ }) + .first() + await page.getByText('Like:306,526').click() + await page.getByText('600/').click() +}) diff --git a/examples/sites/demos/pc/app/statistic/statistic-slot.vue b/examples/sites/demos/pc/app/statistic/statistic-slot.vue new file mode 100644 index 000000000..7dc9c38a0 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-slot.vue @@ -0,0 +1,51 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/statistic-style-composition-api.vue b/examples/sites/demos/pc/app/statistic/statistic-style-composition-api.vue new file mode 100644 index 000000000..7d30b7a63 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-style-composition-api.vue @@ -0,0 +1,29 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/statistic-style.spec.ts b/examples/sites/demos/pc/app/statistic/statistic-style.spec.ts new file mode 100644 index 000000000..aabb4b3cf --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-style.spec.ts @@ -0,0 +1,7 @@ +import { test, expect } from '@playwright/test' + +test('样式用法', async ({ page }) => { + page.on('pageerror', (exception) => expect(exception).toBeNull()) + await page.goto('statistic#statistic-style') + await expect(page.getByText('Like:306,526').first()).toHaveClass(/tiny-statistic__slots/) +}) diff --git a/examples/sites/demos/pc/app/statistic/statistic-style.vue b/examples/sites/demos/pc/app/statistic/statistic-style.vue new file mode 100644 index 000000000..1a07aed3e --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/statistic-style.vue @@ -0,0 +1,41 @@ + + + diff --git a/examples/sites/demos/pc/app/statistic/webdoc/statistic.cn.md b/examples/sites/demos/pc/app/statistic/webdoc/statistic.cn.md new file mode 100644 index 000000000..f2f676707 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/webdoc/statistic.cn.md @@ -0,0 +1,7 @@ +--- +title: Statistic 统计组件 +--- + +# Statistic 统计组件 + +显示统计。 diff --git a/examples/sites/demos/pc/app/statistic/webdoc/statistic.en.md b/examples/sites/demos/pc/app/statistic/webdoc/statistic.en.md new file mode 100644 index 000000000..53958248a --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/webdoc/statistic.en.md @@ -0,0 +1,7 @@ +--- +title: Statistics component +--- + +# Statistics component + +Display statistical data. diff --git a/examples/sites/demos/pc/app/statistic/webdoc/statistic.js b/examples/sites/demos/pc/app/statistic/webdoc/statistic.js new file mode 100644 index 000000000..c1e92de10 --- /dev/null +++ b/examples/sites/demos/pc/app/statistic/webdoc/statistic.js @@ -0,0 +1,46 @@ +export default { + column: '2', + owner: '', + demos: [ + { + demoId: 'basic-usage', + name: { + 'zh-CN': '基本用法', + 'en-US': 'Basic Usage' + }, + desc: { + 'zh-CN': + '通过value设置数字内容,precision设置数字精度值,title设置数字内容标题,prefix设置数字内容前置插槽,suffix设置数字内容后置插槽。', + 'en-US': + 'Set digital content throughvalue,precisionset digital precision value,titleset digital content title,prefixset digital content front slot, andsuffixset digital content rear slot.' + }, + codeFiles: ['basic-usage.vue'] + }, + { + demoId: 'statistic-slot', + name: { + 'zh-CN': '插槽用法', + 'en-US': 'Slot Usage' + }, + desc: { + 'zh-CN': + '通过title设置标题插槽,prefix设置数字前缀插槽,suffix设置数字后缀插槽。', + 'en-US': + 'Set the title slot throughtitle, set the number prefix slot throughprefix, and set the number suffix slot throughsuffix.' + }, + codeFiles: ['statistic-slot.vue'] + }, + { + demoId: 'statistic-style', + name: { + 'zh-CN': '样式用法', + 'en-US': 'Style Usage' + }, + desc: { + 'zh-CN': '通过value-style设置数字样式。', + 'en-US': 'Set the number style throughvalue style.' + }, + codeFiles: ['statistic-style.vue'] + } + ] +} diff --git a/examples/sites/demos/pc/menus.js b/examples/sites/demos/pc/menus.js index 3f4fdb121..d81ac5de4 100644 --- a/examples/sites/demos/pc/menus.js +++ b/examples/sites/demos/pc/menus.js @@ -211,7 +211,8 @@ export const cmpMenus = [ { 'nameCn': '树形控件', 'name': 'Tree', 'key': 'tree' }, { 'nameCn': '穿梭框', 'name': 'Transfer', 'key': 'transfer' }, { 'nameCn': '无限滚动', 'name': 'InfiniteScroll', 'key': 'infinite-scroll' }, - { 'nameCn': '骨架屏', 'name': 'Skeleton', 'key': 'skeleton' } + { 'nameCn': '骨架屏', 'name': 'Skeleton', 'key': 'skeleton' }, + { 'nameCn': '统计', 'name': 'Statistic', 'key': 'statistic' } ] }, { diff --git a/examples/sites/demos/saas/menus.js b/examples/sites/demos/saas/menus.js index e9e7fa25c..24d426abe 100644 --- a/examples/sites/demos/saas/menus.js +++ b/examples/sites/demos/saas/menus.js @@ -26,7 +26,8 @@ const noSaasComponents = [ 'TopBox', 'Watermark', 'Wheel', - 'Skeleton' + 'Skeleton', + 'Statistic' ] // mobile-first上所有分类,pc上都有,因此可以用pc端menu分类进行合并 diff --git a/packages/modules.json b/packages/modules.json index c9dedb6f0..c3d431804 100644 --- a/packages/modules.json +++ b/packages/modules.json @@ -2583,6 +2583,19 @@ "type": "template", "exclude": false }, + "Statistic": { + "path": "vue/src/statistic/index.ts", + "type": "component", + "exclude": false, + "mode": [ + "pc" + ] + }, + "StatisticPc": { + "path": "vue/src/statistic/src/pc.vue", + "type": "template", + "exclude": false + }, "SlideBar": { "path": "vue/src/slide-bar/index.ts", "type": "component", diff --git a/packages/renderless/src/statistic/index.ts b/packages/renderless/src/statistic/index.ts new file mode 100644 index 000000000..b7308a4c5 --- /dev/null +++ b/packages/renderless/src/statistic/index.ts @@ -0,0 +1,22 @@ +import { isFunction } from '../common/type' + +export const isNumber = + ({ props }) => + () => { + return typeof props.value === 'number' + } + +export const getIntegerAndDecimal = + ({ props }) => + () => { + if (isFunction(props.formatter)) { + return props.formatter(props.value) + } + if (!isNumber(props.value)) { + return props.value + } + let displayValue = props.value ? String(props.value).split('.') : '' + let integer = displayValue[0]?.replace(/\B(?=(\d{3})+(?!\d))/g, props.groupSeparator) + let decimal = displayValue[1]?.padEnd(props.precision, '0').slice(0, props.precision > 0 ? props.precision : 0) + return [integer, decimal].join(decimal ? '.' : '') + } diff --git a/packages/renderless/src/statistic/vue.ts b/packages/renderless/src/statistic/vue.ts new file mode 100644 index 000000000..a36c2a671 --- /dev/null +++ b/packages/renderless/src/statistic/vue.ts @@ -0,0 +1,21 @@ +import { getIntegerAndDecimal } from './index' +import type { IStatisticApi, IStatisticState } from '@/types' + +export const api = ['state', 'getIntegerAndDecimal'] + +export const renderless = (props, hooks): IStatisticApi => { + const api: IStatisticApi = { + getIntegerAndDecimal: getIntegerAndDecimal({ props }) + } + const { reactive, computed } = hooks + + const state: IStatisticState = reactive({ + value: computed(() => api.getIntegerAndDecimal(props)) + }) + + Object.assign(api, { + state + }) + + return api +} diff --git a/packages/renderless/types/index.ts b/packages/renderless/types/index.ts index a3d8d5fd7..fee4190cc 100644 --- a/packages/renderless/types/index.ts +++ b/packages/renderless/types/index.ts @@ -157,6 +157,7 @@ export * from './selected-box.type' export * from './shared.type' export * from './skeleton.type' export * from './skeleton-item.type' +export * from './statistic.type' export * from './slide-bar.type' export * from './slider.type' export * from './slider-button.type' diff --git a/packages/renderless/types/statistic.type.ts b/packages/renderless/types/statistic.type.ts new file mode 100644 index 000000000..212c43226 --- /dev/null +++ b/packages/renderless/types/statistic.type.ts @@ -0,0 +1,20 @@ +import type { ExtractPropTypes } from 'vue' +import type { statisticProps, $constants } from '@/statistic/src' +import type { ISharedRenderlessFunctionParams } from './shared.type' + +export type IStatisticProps = ExtractPropTypes + +export type IStatisticConstants = typeof $constants + +export interface IStatisticState { + getIntegerAndDecimal: number | string +} +export interface IStatisticApi { + getIntegerAndDecimal: (value: string | number) => string | undefined +} + +export type IStatisticPcRenderlessParams = ISharedRenderlessFunctionParams & { + state: IStatisticState + props: IStatisticProps + api: IStatisticApi +} diff --git a/packages/theme/src/statistic/index.less b/packages/theme/src/statistic/index.less new file mode 100644 index 000000000..312a9ca6c --- /dev/null +++ b/packages/theme/src/statistic/index.less @@ -0,0 +1,48 @@ +@import '../custom.less'; +@import './vars.less'; + +@statistic-item-prefix-cls: ~'@{css-prefix}statistic'; + +.@{statistic-item-prefix-cls} { + .component-css-vars-statistic(); + + width: 100%; + text-align: center; + + &__title { + font-size: var(--ti-statistic-font-size); + color: var(--ti-statistic-font-color); + font-weight: var(--ti-statistic-title-font-weight); + line-height: var(--ti-statistic-title-line-height); + margin-bottom: var(--ti-statistic-title-margin-bottom); + } + + &__footer-title { + margin-top: var(--ti-statistic-title-margin-bottom); + } + + &__slots { + font-weight: var(--ti-statistic-font-weight); + font-size: var(--ti-statistic-font-size); + color: var(--ti-statistic-font-color); + } + + &__prefix { + margin-right: var(--ti-statistic-prefix-margin-right); + font-weight: var(--ti-statistic-prefix-font-weight); + display: inline-block; + font-size: var(--ti-statistic-prefix-font-size); + } + + &__description { + font-size: var(--ti-statistic-description-font-size); + display: inline-block; + } + + &__suffix { + font-size: var(--ti-statistic-suffix-font-size); + margin-left: var(--ti-statistic-suffix-margin-left); + font-weight: var(--ti-statistic-suffix-font-weight); + display: inline-block; + } +} diff --git a/packages/theme/src/statistic/smb-theme.js b/packages/theme/src/statistic/smb-theme.js new file mode 100644 index 000000000..c6341fb7c --- /dev/null +++ b/packages/theme/src/statistic/smb-theme.js @@ -0,0 +1,6 @@ +export const tinyStatisticSmbTheme = { + 'ti-statistic-font-size': '24px', + 'ti-statistic-prefix-font-size': '24px', + 'ti-statistic-font-color': '#191919', + 'ti-statistic-suffix-font-size': 'var(--ti-common-font-size-4)' +} diff --git a/packages/theme/src/statistic/vars.less b/packages/theme/src/statistic/vars.less new file mode 100644 index 000000000..2849fae15 --- /dev/null +++ b/packages/theme/src/statistic/vars.less @@ -0,0 +1,28 @@ +.component-css-vars-statistic() { + // 标题字体大小 + --ti-statistic-font-size: var(--ti-common-font-size-base); + // 标题字体颜色 + --ti-statistic-font-color: var(--ti-common-color-text-weaken); + // 标题字体粗细 + --ti-statistic-title-font-weight: var(--ti-common-font-weight-5); + // 标题下间距 + --ti-statistic-title-margin-bottom: var(--ti-common-space-base); + // 标题行高 + --ti-statistic-title-line-height: var(ti-common-line-height-4); + // 前缀插槽字体粗细 + --ti-statistic-font-weight: var(--ti-common-font-weight-5); + // 前缀缀插槽间距值 + --ti-statistic-prefix-margin-right: var(--ti-common-space-6); + // 前缀字体大小 + --ti-statistic-prefix-font-size: var(--ti-common-font-size-4); + // 前缀字体粗细 + --ti-statistic-prefix-font-weight: var(--ti-common-font-weight-5); + // 后缀插槽间距值 + --ti-statistic-suffix-margin-left: var(--ti-common-space-6); + // 后缀字体大小 + --ti-statistic-suffix-font-size: var(--ti-common-font-size-4); + // 后缀字体粗细 + --ti-statistic-suffix-font-weight: var(--ti-common-font-weight-5); + // 数字内容字体 + --ti-statistic-description-font-size: var(--ti-common-font-size-4); +} diff --git a/packages/vue/src/statistic/__tests__/statistic.test.tsx b/packages/vue/src/statistic/__tests__/statistic.test.tsx new file mode 100644 index 000000000..b526946df --- /dev/null +++ b/packages/vue/src/statistic/__tests__/statistic.test.tsx @@ -0,0 +1,3 @@ +import { describe } from 'vitest' + +describe('PC Mode', () => {}) diff --git a/packages/vue/src/statistic/index.ts b/packages/vue/src/statistic/index.ts new file mode 100644 index 000000000..c98829b3f --- /dev/null +++ b/packages/vue/src/statistic/index.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2022 - present TinyVue Authors. + * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ +import Statistic from './src/index' +import '@opentiny/vue-theme/statistic/index.less' +import { version } from './package.json' + +Statistic.model = { + prop: 'modelValue', + event: 'update:modelValue' +} + +/* istanbul ignore next */ +Statistic.install = function (Vue) { + Vue.component(Statistic.name, Statistic) +} + +Statistic.version = version + +/* istanbul ignore next */ +if (process.env.BUILD_TARGET === 'runtime') { + if (typeof window !== 'undefined' && window.Vue) { + Statistic.install(window.Vue) + } +} + +export default Statistic diff --git a/packages/vue/src/statistic/package.json b/packages/vue/src/statistic/package.json new file mode 100644 index 000000000..bb1be9233 --- /dev/null +++ b/packages/vue/src/statistic/package.json @@ -0,0 +1,26 @@ +{ + "name": "@opentiny/vue-statistic", + "version": "3.7.0", + "description": "", + "main": "lib/index.js", + "module": "index.ts", + "sideEffects": false, + "type": "module", + "devDependencies": { + "@opentiny-internal/vue-test-utils": "workspace:*", + "vitest": "^0.31.0" + }, + "scripts": { + "build": "pnpm -w build:ui $npm_package_name", + "//postversion": "pnpm build" + }, + "dependencies": { + "@opentiny/vue-renderless": "workspace:~", + "@opentiny/vue-common": "workspace:~", + "@opentiny/vue-layout": "workspace:~", + "@opentiny/vue-row": "workspace:~", + "@opentiny/vue-col": "workspace:~", + "@opentiny/vue-theme": "workspace:~" + }, + "license": "MIT" +} diff --git a/packages/vue/src/statistic/src/index.ts b/packages/vue/src/statistic/src/index.ts new file mode 100644 index 000000000..fe53422a4 --- /dev/null +++ b/packages/vue/src/statistic/src/index.ts @@ -0,0 +1,44 @@ +import type { PropType } from '@opentiny/vue-common' +import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' +import template from 'virtual-template?pc' + +export const $constants = { + PREFIX: 'tiny-statistic' +} + +export const definePropType = (val: any): PropType => val + +export const statisticProps = { + ...$props, + _constants: { + type: Object, + default: () => $constants + }, + precision: { + type: Number, + default: 0 + }, + formatter: Function, + value: { + type: definePropType([Number, Object]), + default: 0 + }, + prefix: String, + suffix: String, + title: [String, Object], + valueStyle: { + type: [String, Object, Array] + }, + groupSeparator: { + type: String, + default: ',' + } +} + +export default defineComponent({ + name: $prefix + 'Statistic', + props: statisticProps, + setup(props, context) { + return $setup({ props, context, template }) + } +}) diff --git a/packages/vue/src/statistic/src/pc.vue b/packages/vue/src/statistic/src/pc.vue new file mode 100644 index 000000000..799c36ddd --- /dev/null +++ b/packages/vue/src/statistic/src/pc.vue @@ -0,0 +1,51 @@ + + +