Skip to content

Commit

Permalink
feat: added KStatistic component
Browse files Browse the repository at this point in the history
  • Loading branch information
baiwusanyu-c committed Dec 25, 2023
1 parent b8ed920 commit 71c0f1e
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 360 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Test: KStatistic > props: cls 1`] = `"<div class=\\"k-statistic k-statistic--base k-statistic--test\\"></div>"`;
exports[`Test: KStatistic > props: cls 1`] = `"<div class=\\"k-statistic k-statistic--test\\"> <div class=\\"k-statistic__content\\"> <span class=\\"k-statistic__value\\">0</span> </div></div>"`;
exports[`Test: KStatistic > props: title 1`] = `"<div class=\\"k-statistic\\"><div class=\\"k-statistic__head\\">test-title</div> <div class=\\"k-statistic__content\\"> <span class=\\"k-statistic__value\\">0</span> </div></div>"`;
exports[`Test: KStatistic > props: value 1`] = `"<div class=\\"k-statistic\\"> <div class=\\"k-statistic__content\\"> <span class=\\"k-statistic__value\\">57,454,157</span> </div></div>"`;
exports[`Test: KStatistic > slot: suffix 1`] = `"<div class=\\"k-statistic\\"><div class=\\"k-statistic__head\\">Daily active users</div> <div class=\\"k-statistic__content\\"> <span class=\\"k-statistic__value\\">268,500</span> <div class=\\"k-statistic__suffix\\"><span slot=\\"suffix\\">suffix</span></div></div></div>"`;
7 changes: 7 additions & 0 deletions components/Statistic/__test__/fixture/prefix.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
import { KStatistic } from '@ikun-ui/statistic';
</script>

<KStatistic title="Daily active users" value={268500}>
<span slot="prefix">prefix</span>
</KStatistic>
7 changes: 7 additions & 0 deletions components/Statistic/__test__/fixture/suffix.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
import { KStatistic } from '@ikun-ui/statistic';
</script>

<KStatistic title="Daily active users" value={268500}>
<span slot="suffix">suffix</span>
</KStatistic>
89 changes: 81 additions & 8 deletions components/Statistic/__test__/statistic.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { afterEach, expect, test, describe, beforeEach } from 'vitest';
import KStatistic from '../src';
import KStatisticSuffix from './fixture/suffix.svelte';
import KStatisticPrefix from './fixture/prefix.svelte';
import { tick } from 'svelte';

let host: HTMLElement;
let host;

const initHost = () => {
host = document.createElement('div');
host = globalThis.document.createElement('div');
host.setAttribute('id', 'host');
document.body.appendChild(host);
globalThis.document.body.appendChild(host);
};
beforeEach(() => {
initHost();
Expand All @@ -17,17 +20,87 @@ afterEach(() => {

describe('Test: KStatistic', () => {
test('props: cls', async () => {
// @ts-ignore
const instance = new KStatistic({
target: host,
props: {
cls: 'k-statistic--test'
}
});
expect(instance).toBeTruthy();
expect(
(host as HTMLElement)!.innerHTML.includes('k-statistic--test')
).toBeTruthy();
expect(host!.innerHTML.includes('k-statistic--test')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});
})


test('props: title', async () => {
// @ts-ignore
const instance = new KStatistic({
target: host,
props: {
title: 'test-title'
}
});
expect(instance).toBeTruthy();
expect(host.querySelector('.k-statistic__head')).toBeTruthy();
expect(host!.innerHTML.includes('test-title')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});

test('props: value', async () => {
// @ts-ignore
const instance = new KStatistic({
target: host,
props: {
value: 57454157
}
});
expect(instance).toBeTruthy();
expect(host.querySelector('.k-statistic__content')).toBeTruthy();
expect(host.querySelector('.k-statistic__value')).toBeTruthy();
expect(host!.innerHTML.includes('57,454,157')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});

test('props: precision', async () => {
// @ts-ignore
const instance = new KStatistic({
target: host,
props: {
precision: 6,
value: 268500.123456
}
});
expect(instance).toBeTruthy();
expect(host.querySelector('.k-statistic__content')).toBeTruthy();
expect(host.querySelector('.k-statistic__value')).toBeTruthy();
expect(host!.innerHTML.includes('268,500.123456')).toBeTruthy();
// @ts-ignore
instance.$set({ precision: 4 });
await tick();
expect(host!.innerHTML.includes('268,500.1234')).toBeTruthy();
});

test('slot: prefix', async () => {
// @ts-ignore
const instance = new KStatisticPrefix({
target: host
});
expect(instance).toBeTruthy();
expect(host.querySelector('.k-statistic__content')).toBeTruthy();
expect(host.querySelector('.k-statistic__value')).toBeTruthy();
expect(host.querySelector('.k-statistic__prefix')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});

test('slot: suffix', async () => {
// @ts-ignore
const instance = new KStatisticSuffix({
target: host
});
expect(instance).toBeTruthy();
expect(host.querySelector('.k-statistic__content')).toBeTruthy();
expect(host.querySelector('.k-statistic__value')).toBeTruthy();
expect(host.querySelector('.k-statistic__suffix')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});
});
94 changes: 47 additions & 47 deletions components/Statistic/package.json
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
{
"name": "@ikun-ui/statistic",
"version": "0.1.0",
"type": "module",
"main": "src/index.ts",
"types": "src/index.d.ts",
"svelte": "src/index.ts",
"keywords": [
"svelte",
"svelte3",
"web component",
"component",
"react",
"vue",
"svelte-kit",
"dx"
],
"files": [
"dist",
"package.json"
],
"scripts": {
"build": "npm run build:js && npm run build:svelte",
"build:js": "tsc -p . --outDir dist/ --rootDir src/",
"build:svelte": "svelte-strip strip src/ dist",
"publish:pre": "node ../../scripts/pre-publish.js",
"publish:npm": "pnpm run publish:pre && pnpm publish --no-git-checks --access public"
},
"publishConfig": {
"access": "public",
"main": "dist/index.js",
"module": "dist/index.js",
"svelte": "dist/index.js",
"types": "dist/index.d.ts"
},
"dependencies": {
"@ikun-ui/icon": "workspace:*",
"@ikun-ui/utils": "workspace:*",
"baiwusanyu-utils": "^1.0.16",
"clsx": "^2.0.0"
},
"devDependencies": {
"@tsconfig/svelte": "^5.0.2",
"svelte-strip": "^2.0.0",
"tslib": "^2.6.2",
"typescript": "^5.3.2"
}
}
"name": "@ikun-ui/statistic",
"version": "0.1.0",
"type": "module",
"main": "src/index.ts",
"types": "src/index.d.ts",
"svelte": "src/index.ts",
"keywords": [
"svelte",
"svelte3",
"web component",
"component",
"react",
"vue",
"svelte-kit",
"dx"
],
"files": [
"dist",
"package.json"
],
"scripts": {
"build": "npm run build:js && npm run build:svelte",
"build:js": "tsc -p . --outDir dist/ --rootDir src/",
"build:svelte": "svelte-strip strip src/ dist",
"publish:pre": "node ../../scripts/pre-publish.js",
"publish:npm": "pnpm run publish:pre && pnpm publish --no-git-checks --access public"
},
"publishConfig": {
"access": "public",
"main": "dist/index.js",
"module": "dist/index.js",
"svelte": "dist/index.js",
"types": "dist/index.d.ts"
},
"dependencies": {
"@ikun-ui/icon": "workspace:*",
"@ikun-ui/utils": "workspace:*",
"baiwusanyu-utils": "^1.0.16",
"clsx": "^2.0.0"
},
"devDependencies": {
"@tsconfig/svelte": "^5.0.2",
"svelte-strip": "^2.0.0",
"tslib": "^2.6.2",
"typescript": "^5.3.2"
}
}
113 changes: 55 additions & 58 deletions components/Statistic/src/index.svelte
Original file line number Diff line number Diff line change
@@ -1,71 +1,68 @@
<script lang="ts">
import { getPrefixCls } from '@ikun-ui/utils';
import { getPrefixCls } from '@ikun-ui/utils';
import { clsx } from 'clsx';
import type { KStatisticProps } from "./types";
import { isFunction, isNumber } from "baiwusanyu-utils";
import type { KStatisticProps } from './types';
import { isFunction, isNumber } from 'baiwusanyu-utils';
export let decimalSeparator: KStatisticProps["decimalSeparator"] = '.';
export let groupSeparator: KStatisticProps["groupSeparator"] = ',';
export let precision: KStatisticProps["precision"] = 0;
export let formatter: KStatisticProps["formatter"] = undefined;
export let value: KStatisticProps["value"] = 0;
export let prefix: KStatisticProps["prefix"] = undefined;
export let suffix: KStatisticProps["suffix"] = undefined;
export let title: KStatisticProps["title"] = undefined;
export let valueStyle: KStatisticProps["valueStyle"] = undefined;
export let cls: KStatisticProps["cls"] = undefined;
export let attrs: KStatisticProps["attrs"] = {};
export let decimalSeparator: KStatisticProps['decimalSeparator'] = '.';
export let groupSeparator: KStatisticProps['groupSeparator'] = ',';
export let precision: KStatisticProps['precision'] = 0;
export let formatter: KStatisticProps['formatter'] = undefined;
export let value: KStatisticProps['value'] = 0;
export let prefix: KStatisticProps['prefix'] = undefined;
export let suffix: KStatisticProps['suffix'] = undefined;
export let title: KStatisticProps['title'] = undefined;
export let valueStyle: KStatisticProps['valueStyle'] = undefined;
export let cls: KStatisticProps['cls'] = undefined;
export let attrs: KStatisticProps['attrs'] = {};
$: displayValue = () => {
if (isFunction(formatter)) return formatter!(value)
$: displayValue = () => {
if (isFunction(formatter)) return formatter!(value);
if (!isNumber(value)) return value
if (!isNumber(value)) return value;
let [integer, decimal = ''] = String(value).split('.')
decimal = decimal
.padEnd(precision, '0')
.slice(0, precision > 0 ? precision : 0)
integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator)
return [integer, decimal].join(decimal ? decimalSeparator : '')
}
let [integer, decimal = ''] = String(value).split('.');
decimal = decimal.padEnd(precision, '0').slice(0, precision > 0 ? precision : 0);
integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator);
return [integer, decimal].join(decimal ? decimalSeparator : '');
};
const namespaceCls = getPrefixCls('statistic');
$: cnames = clsx(namespaceCls, cls);
$: headCls = clsx(`${namespaceCls}__head`);
$: contentCls =clsx(`${namespaceCls}__content`);
$: prefixCls = clsx(`${namespaceCls}__prefix`);
$: valueCls = clsx(`${namespaceCls}__value`);
$: suffixCls = clsx(`${namespaceCls}__suffix`);
const namespaceCls = getPrefixCls('statistic');
$: cnames = clsx(namespaceCls, cls);
$: headCls = clsx(`${namespaceCls}__head`);
$: contentCls = clsx(`${namespaceCls}__content`);
$: prefixCls = clsx(`${namespaceCls}__prefix`);
$: valueCls = clsx(`${namespaceCls}__value`);
$: suffixCls = clsx(`${namespaceCls}__suffix`);
</script>

<div class={cnames} {...$$restProps} {...attrs}>
{#if $$slots.title || title}
<div class={headCls}>
<slot name="title">
{ title }
</slot>
</div>
{/if}
<div class={contentCls}>
{#if $$slots.title || title}
<div class={headCls}>
<slot name="title">
{title}
</slot>
</div>
{/if}
<div class={contentCls}>
{#if $$slots.prefix || prefix}
<div class={prefixCls}>
<slot name="prefix">
<span>{prefix}</span>
</slot>
</div>
{/if}

{#if $$slots.prefix || prefix}
<div class={prefixCls}>
<slot name="prefix">
<span>{ prefix }</span>
</slot>
</div>
{/if}
<span class={valueCls} style={valueStyle}>
{displayValue()}
</span>

<span class={valueCls} style={valueStyle}>
{ displayValue() }
</span>

{#if $$slots.suffix || suffix}
<div class={suffixCls}>
<slot name="suffix">
<span>{ suffix }</span>
</slot>
</div>
{/if}
</div>
{#if $$slots.suffix || suffix}
<div class={suffixCls}>
<slot name="suffix">
<span>{suffix}</span>
</slot>
</div>
{/if}
</div>
</div>
2 changes: 1 addition & 1 deletion components/Statistic/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
import Statistic from './index.svelte';
export { Statistic as KStatistic };

export default Statistic;
export default Statistic;
Loading

0 comments on commit 71c0f1e

Please sign in to comment.