Skip to content
This repository was archived by the owner on Oct 7, 2023. It is now read-only.
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
27 changes: 27 additions & 0 deletions __tests__/unit/util/padding.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { normalPadding } from '../../../src/util';

describe('padding', () => {
test('undefined', async () => {
expect(normalPadding(undefined)).toStrictEqual([0, 0, 0, 0]);
});

test('number', async () => {
expect(normalPadding(1)).toStrictEqual([1, 1, 1, 1]);
});

test('array1', async () => {
expect(normalPadding([2])).toStrictEqual([2, 2, 2, 2]);
});

test('array2', async () => {
expect(normalPadding([1, 2])).toStrictEqual([1, 2, 1, 2]);
});

test('array3', async () => {
expect(normalPadding([1, 2, 3])).toStrictEqual([1, 2, 3, 2]);
});

test('array4', async () => {
expect(normalPadding([1, 2, 3, 4])).toStrictEqual([1, 2, 3, 4]);
});
});
35 changes: 35 additions & 0 deletions __tests__/unit/util/style.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getDefaultStyle, getStateStyle } from '../../../src/util';

const defaultStyle = {
fill: 'red',
stroke: 'green',
lineWidth: 10,
};
const active = {
fill: 'green',
stroke: 'blue',
};

const inactive = {
fill: 'gray',
};

describe('getStyle', () => {
test('getDefaultStyle', async () => {
expect(getDefaultStyle(defaultStyle)).toStrictEqual(defaultStyle);
expect(getDefaultStyle({ ...defaultStyle, active })).toStrictEqual(defaultStyle);
expect(getDefaultStyle({ ...defaultStyle, active, inactive })).toStrictEqual(defaultStyle);
});

test('getStateStyle', async () => {
expect(getStateStyle(defaultStyle)).toStrictEqual(defaultStyle);
expect(getStateStyle({ ...defaultStyle, active })).toStrictEqual(defaultStyle);
expect(getStateStyle({ ...defaultStyle, active }, 'active')).toStrictEqual(active);
expect(getStateStyle({ ...defaultStyle, inactive }, 'inactive')).toStrictEqual(inactive);
expect(getStateStyle({ ...defaultStyle, active }, 'active', true)).toStrictEqual({ ...defaultStyle, ...active });
expect(getStateStyle({ ...defaultStyle, inactive }, 'inactive', true)).toStrictEqual({
...defaultStyle,
...inactive,
});
});
});
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { ShapeAttrs, ShapeCfg, CustomElement, DisplayObject } from '@antv/g';
export { MixAttrs } from './util/style';
2 changes: 2 additions & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export { svg2marker } from './svg2marker';
export { measureTextWidth, getEllipsisText } from './text';
export { toPrecision } from './utils';
export { normalPadding } from './padding';
export { getDefaultStyle, getStateStyle } from './style';
29 changes: 29 additions & 0 deletions src/util/padding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { isNumber, isArray } from '@antv/util';

type NormalPaddingType = [number, number, number, number];

/**
* 规范化padding
*/
export function normalPadding(padding: number | number[]): NormalPaddingType {
if (isNumber(padding)) {
return [padding, padding, padding, padding];
}
if (isArray(padding)) {
const len = (padding as number[]).length;

if (len === 1) {
return [padding[0], padding[0], padding[0], padding[0]];
}
if (len === 2) {
return [padding[0], padding[1], padding[0], padding[1]];
}
if (len === 3) {
return [padding[0], padding[1], padding[2], padding[1]];
}
if (len === 4) {
return padding as NormalPaddingType;
}
}
return [0, 0, 0, 0];
}
44 changes: 44 additions & 0 deletions src/util/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { clone, deepMix, get } from '@antv/util';
import { ShapeAttrs } from '@antv/g';

const STATE_LIST = ['active', 'inactive', 'checked', 'unchecked', 'enable', 'disabled'] as const;
export type StyleState = typeof STATE_LIST[number];

export type MixAttrs = ShapeAttrs &
{
[state in StyleState]?: ShapeAttrs;
};

/**
* 从带状态样式中返回移除了状态样式的默认样式
*/
export function getDefaultStyle(style: MixAttrs): ShapeAttrs {
const duplicateStyle = clone(style);
// 移除其他带状态的样式得到默认样式
STATE_LIST.forEach((state) => {
if (state in duplicateStyle) delete duplicateStyle[state];
});
return duplicateStyle;
}

/**
* 对于格式为:
* style: ShapeAttrs & {
* [state: string]?: ShapeAttrs,
* }
* 的带状态样式,根据状态提取出样式
* 默认返回默认样式
* @param style 混合样式
* @param state 状态
* @param isMerge 是否将状态样式与默认样式合并
*/
export function getStateStyle(style: MixAttrs, state?: StyleState, isMerge: boolean = false): ShapeAttrs {
if (!state) {
return getDefaultStyle(style);
}
const stateStyle = get(style, state);
if (isMerge) {
return deepMix({}, getDefaultStyle(style), stateStyle);
}
return stateStyle;
}