Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ English | [简体中文](./README.zh-CN.md)
| :------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| [@visactor/vchart-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-theme/blob/main/LICENSE) |
| [@visactor/vchart-semi-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-semi-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-semi-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-semi-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-semi-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-semi-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-semi-theme/blob/main/LICENSE) |
| [@visactor/vchart-keystone-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-keystone-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-keystone-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-keystone-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-keystone-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-keystone-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-theme/blob/main/LICENSE) |
| [@visactor/vchart-arco-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-arco-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-arco-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-arco-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-arco-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-arco-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-arco-theme/blob/main/LICENSE) |
| [@visactor/vchart-tt-platform-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-tt-platform-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-tt-platform-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-tt-platform-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-tt-platform-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-tt-platform-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-tt-platform-theme/blob/main/LICENSE) |
| [@visactor/vchart-ve-o-theme](https://github.com/VisActor/vchart-theme/tree/main/packages/vchart-ve-o-theme) | [![npm Version](https://img.shields.io/npm/v/@visactor/vchart-ve-o-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-ve-o-theme) [![npm Download](https://img.shields.io/npm/dm/@visactor/vchart-ve-o-theme.svg)](https://www.npmjs.com/package/@visactor/vchart-ve-o-theme) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/visactor/vchart-ve-o-theme/blob/main/LICENSE) |
Expand All @@ -32,9 +33,10 @@ This repository includes the following packages:

1. [vchart-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-theme): contains all static extension themes
2. [vchart-semi-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-semi-theme): dynamic chart themes used in conjunction with [Semi Design](https://github.com/DouyinFE/semi-design).
3. [vchart-arco-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-arco-theme): dynamic chart themes used in conjunction with [ArcoDesign](https://github.com/arco-design).
4. [vchart-tt-platform-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-tt-platform-theme): dynamic chart themes used in conjunction with [Semi Design](https://github.com/DouyinFE/semi-design) for TT platform.
5. [vchart-ve-o-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-ve-o-theme): dynamic chart themes used in conjunction with [ArcoDesign](https://github.com/arco-design) for O Design.
3. [vchart-keystone-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-keystone-theme): dynamic chart themes used in conjunction with Keystone Design.
4. [vchart-arco-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-arco-theme): dynamic chart themes used in conjunction with [ArcoDesign](https://github.com/arco-design).
5. [vchart-tt-platform-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-tt-platform-theme): dynamic chart themes used in conjunction with [Semi Design](https://github.com/DouyinFE/semi-design) for TT platform.
6. [vchart-ve-o-theme](https://github.com/VisActor/vchart-theme/tree/develop/packages/vchart-ve-o-theme): dynamic chart themes used in conjunction with [ArcoDesign](https://github.com/arco-design) for O Design.

# Usage

Expand Down
79 changes: 79 additions & 0 deletions packages/vchart-keystone-theme/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# @visactor/vchart-keystone-theme

Keystone Design theme package for VChart.

This package provides standard VChart themes based on the Keystone chart theme configuration. The chart theme source of truth is the Keystone chart theme package in the Byted Web Components repository. This package includes a Keystone design-token snapshot so it can be published externally without depending on internal packages.

## Install

```bash
npm install @visactor/vchart @visactor/vchart-keystone-theme
```

## Usage

```ts
import VChart from '@visactor/vchart';
import { initVChartKeystoneTheme } from '@visactor/vchart-keystone-theme';

initVChartKeystoneTheme();

const spec = {
type: 'bar',
data: [
{
id: 'data',
values: [
{ type: 'A', value: 10 },
{ type: 'B', value: 20 }
]
}
],
xField: 'type',
yField: 'value'
};

const chart = new VChart(spec, { dom: 'chart' });
chart.renderSync();
```

## Optional CSS variables

If your application already provides Keystone CSS variables, no CSS import is required.

If your application does not provide Keystone CSS variables, import the bundled snapshot CSS:

```ts
import '@visactor/vchart-keystone-theme/index.css';
```

The JavaScript entrypoint does not automatically import CSS.

## Direct theme usage

```ts
import { keystoneDesignLight, keystoneDesignDark } from '@visactor/vchart-keystone-theme';
```

## Token snapshot

This package exports a Keystone design-token snapshot for chart theme compatibility:

```ts
import { ks, getCSSVariableValue } from '@visactor/vchart-keystone-theme';
```

These exports are bundled with this theme package and are not intended to replace the Keystone design-token package.

## Scope

This package is a standard VChart theme package. It does not include Keystone chart spec helper APIs such as `createKsBarChartSpec`, `createKsLineChartSpec`, custom DOM tooltip rendering, RTL spec wrapping, or chart data formatting helpers.

## Theme JSON files

<!-- ThemeListBegin -->
<!-- 以下为自动生成 -->
- [keystoneDesignLight](https://raw.githubusercontent.com/VisActor/vchart-theme/main/packages/vchart-keystone-theme/public/keystoneDesignLight.json) Keystone Design - light
- [keystoneDesignDark](https://raw.githubusercontent.com/VisActor/vchart-theme/main/packages/vchart-keystone-theme/public/keystoneDesignDark.json) Keystone Design - dark
<!-- 以上为自动生成 -->
<!-- ThemeListEnd -->
135 changes: 135 additions & 0 deletions packages/vchart-keystone-theme/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import fs from 'fs';
import path from 'path';
import { getCSSVariableValue, ks } from '../src/design-tokens';
import { getBarTheme, getTheme, theme } from '../src/common';
import {
allThemeMap,
initVChartKeystoneTheme,
keystoneDesignDark,
keystoneDesignLight,
VChartKeystoneThemeHelper
} from '../src';

describe('vchart-keystone-theme design tokens', () => {
beforeEach(() => {
document.documentElement.style.setProperty('--ks-test-color', '#123456');
});

afterEach(() => {
document.documentElement.style.removeProperty('--ks-test-color');
});

it('exports the Keystone token snapshot', () => {
expect(ks.ref.color.neutral[500]).toBe('var(--ks-ref-color-neutral-500, #87898b)');
});

it('reads CSS variables by raw variable name', () => {
expect(getCSSVariableValue('--ks-test-color').trim()).toBe('#123456');
});

it('reads cached CSS variables by var() call syntax', () => {
expect(getCSSVariableValue('var(--ks-test-color)').trim()).toBe('#123456');
});

it('caches no-DOM fallback values for raw and var() names', () => {
const originalDocument = global.document;
const originalGetComputedStyle = global.getComputedStyle;

try {
(global as any).document = undefined;
(global as any).getComputedStyle = undefined;

jest.isolateModules(() => {
const { getCSSVariableValue: getIsolatedCSSVariableValue } = require('../src/design-tokens/getCSSVariableValue');

expect(getIsolatedCSSVariableValue('--ks-no-dom-cache')).toBe('var(--ks-no-dom-cache)');

(global as any).document = originalDocument;
(global as any).getComputedStyle = originalGetComputedStyle;
document.documentElement.style.setProperty('--ks-no-dom-cache', '#abcdef');

expect(getIsolatedCSSVariableValue('var(--ks-no-dom-cache)').trim()).toBe('var(--ks-no-dom-cache)');
});
} finally {
(global as any).document = originalDocument;
(global as any).getComputedStyle = originalGetComputedStyle;
document.documentElement.style.removeProperty('--ks-no-dom-cache');
}
});
});

describe('vchart-keystone-theme common theme utilities', () => {
it('exports the Keystone chart theme defaults', () => {
expect(theme.component?.axis?.label?.style?.fontFamily).toBe('TikTok Sans Text');
expect(theme.component?.discreteLegend?.item?.shape?.style?.symbolType).toBe('circle');
expect(theme.chart?.pie?.mark?.arc?.style?.padAngle).toBe(0.01);
expect(theme.markByName?.area?.style?.fillOpacity).toBe(0.2);
});

it('creates a theme with legend size and RTL settings', () => {
const rtlTheme = getTheme({ legendSize: 'lg', isRtl: true });
expect(rtlTheme.component?.discreteLegend?.position).toBe('start');
expect(rtlTheme.component?.discreteLegend?.reversed).toBe(true);
expect(rtlTheme.component?.discreteLegend?.item?.shape?.style?.size).toBe(8);
});

it('creates a bar theme with non-stacked corner radius', () => {
const barTheme = getBarTheme({
stack: false,
size: 'md',
direction: 'vertical',
legendSize: 'md',
isRtl: false
});
expect(barTheme.markByName?.bar?.style?.cornerRadius).toEqual([4, 4, 0, 0]);
});
});

describe('vchart-keystone-theme export output', () => {
it('exports concrete Keystone token values in public theme JSON', () => {
const themeJsonPath = path.resolve(__dirname, '../public/keystoneDesignLight.json');
const exportedTheme = JSON.parse(fs.readFileSync(themeJsonPath, 'utf8'));

expect(exportedTheme.colorScheme.default.dataScheme[0]).toBe('#8987f6');
expect(exportedTheme.colorScheme.default.dataScheme).not.toContain('var(--ks-color-data-data1-fill)');
expect(exportedTheme.component.axis.label.style.color).toBe('#87898b');
});
});

describe('vchart-keystone-theme public API', () => {
it('exports light and dark Keystone themes', () => {
expect(keystoneDesignLight.name).toBe('keystoneDesignLight');
expect(keystoneDesignLight.type).toBe('light');
expect(keystoneDesignLight.description).toBe('Keystone Design - light');
expect(keystoneDesignLight.component?.axis?.label?.style?.fontFamily).toBe('TikTok Sans Text');

expect(keystoneDesignDark.name).toBe('keystoneDesignDark');
expect(keystoneDesignDark.type).toBe('dark');
expect(keystoneDesignDark.description).toBe('Keystone Design - dark');
expect(keystoneDesignDark.component?.axis?.label?.style?.fontFamily).toBe('TikTok Sans Text');
});

it('exports all themes in allThemeMap', () => {
expect(allThemeMap.get('keystoneDesignLight')).toBe(keystoneDesignLight);
expect(allThemeMap.get('keystoneDesignDark')).toBe(keystoneDesignDark);
});

it('initializes through the Keystone helper', () => {
const helper = initVChartKeystoneTheme();
expect(helper).toBeInstanceOf(VChartKeystoneThemeHelper);
expect(VChartKeystoneThemeHelper.themeNamePrefix).toBe('keystoneDesign');
});

it('generates the Keystone light theme without rewriting its array color scheme', () => {
const helper = new VChartKeystoneThemeHelper({ isWatchingMode: false });
const generatedTheme = helper.generateTheme({ mode: 'light' });
const generatedDefaultColorScheme = generatedTheme.colorScheme?.default;

expect(generatedDefaultColorScheme).toBe(keystoneDesignLight.colorScheme?.default);
expect(Array.isArray(generatedDefaultColorScheme)).toBe(true);
expect(generatedDefaultColorScheme).toHaveLength(9);
expect(generatedDefaultColorScheme).toEqual(
Array.from({ length: 9 }, (_, index) => getCSSVariableValue(`--ks-color-data-data${index + 1}-fill`))
);
});
});
13 changes: 13 additions & 0 deletions packages/vchart-keystone-theme/bundler.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @type {Partial<import('@internal/bundler').Config>}
*/
module.exports = {
formats: ['cjs', 'es', 'umd'],
outputDir: {
es: 'esm',
cjs: 'cjs',
umd: 'build'
},
name: 'vchart-keystone-theme',
umdOutputFilename: 'index'
};
Loading
Loading