@pushwoosh/kit-charts 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ export declare const DEFAULT_SURFACE_COLOR: string;
15
15
  * yet. Two neutrals, not one: white on the mid greys a threshold is painted in
16
16
  * reads at 2.8:1, far under the 4.5:1 small text needs.
17
17
  */
18
- export declare const DEFAULT_ON_FILL_TEXT_COLOR: string;
18
+ export declare const DEFAULT_ON_FILL_TEXT_COLOR = "#FFFFFF";
19
19
  /** Whichever of the two neutrals reads better on a fill. */
20
20
  export declare function textColorOn(fill: string): string;
21
21
  export declare const DEFAULT_TOOLTIP_SURFACE_COLOR: string;
@@ -17,7 +17,9 @@ export const DEFAULT_SURFACE_COLOR = Color.CLEAR;
17
17
  * yet. Two neutrals, not one: white on the mid greys a threshold is painted in
18
18
  * reads at 2.8:1, far under the 4.5:1 small text needs.
19
19
  */
20
- export const DEFAULT_ON_FILL_TEXT_COLOR = Color.CLEAR;
20
+ // Literal white rather than `Color.CLEAR`: the fill is the caller's, so the ink on it
21
+ // must stay readable instead of turning #323233 with the dark theme.
22
+ export const DEFAULT_ON_FILL_TEXT_COLOR = '#FFFFFF';
21
23
  const ON_FILL_DARK_TEXT_COLOR = Color.BRAND_BLACK;
22
24
  const linearChannel = value => {
23
25
  const unit = value / 255;
@@ -32,15 +34,16 @@ const luminance = color => {
32
34
  return 0.2126 * linearChannel(rgba[0]) + 0.7152 * linearChannel(rgba[1]) + 0.0722 * linearChannel(rgba[2]);
33
35
  };
34
36
  const contrast = (one, other) => (Math.max(one, other) + 0.05) / (Math.min(one, other) + 0.05);
35
- const LIGHT_TEXT_LUMINANCE = luminance(DEFAULT_ON_FILL_TEXT_COLOR) ?? 1;
36
- const DARK_TEXT_LUMINANCE = luminance(ON_FILL_DARK_TEXT_COLOR) ?? 0;
37
37
  /** Whichever of the two neutrals reads better on a fill. */
38
38
  export function textColorOn(fill) {
39
39
  const behind = luminance(fill);
40
40
  if (behind === null) {
41
41
  return DEFAULT_ON_FILL_TEXT_COLOR;
42
42
  }
43
- return contrast(behind, LIGHT_TEXT_LUMINANCE) >= contrast(behind, DARK_TEXT_LUMINANCE) ? DEFAULT_ON_FILL_TEXT_COLOR : ON_FILL_DARK_TEXT_COLOR;
43
+ // Read per call, not once: both neutrals are tokens and swap literals when the theme does.
44
+ const light = luminance(DEFAULT_ON_FILL_TEXT_COLOR) ?? 1;
45
+ const dark = luminance(ON_FILL_DARK_TEXT_COLOR) ?? 0;
46
+ return contrast(behind, light) >= contrast(behind, dark) ? DEFAULT_ON_FILL_TEXT_COLOR : ON_FILL_DARK_TEXT_COLOR;
44
47
  }
45
48
  // Chart tooltips follow the product hint style: dark bubble, light text.
46
49
  export const DEFAULT_TOOLTIP_SURFACE_COLOR = Color.BRAND_BLACK;
@@ -1,9 +1,12 @@
1
+ import { type ThemeName } from '@pushwoosh/kit-constants';
1
2
  import { type ColorScale, type ColorStop } from '../types/scale';
2
3
  export interface ColorScaleOptions {
3
4
  domain: readonly [number, number];
4
5
  stops: readonly ColorStop[];
5
6
  }
6
7
  type Rgba = [number, number, number, number];
8
+ /** Theme the page is painted in; a chart reads it the way CSS does, off `<html>`. */
9
+ export declare const activeTheme: () => ThemeName;
7
10
  export declare const parseColor: (color: string) => Rgba | null;
8
11
  export declare function createColorScale(options: ColorScaleOptions): ColorScale;
9
12
  export {};
@@ -1,3 +1,4 @@
1
+ import { Color, DEFAULT_THEME, getThemeColors, THEME_ATTRIBUTE } from '@pushwoosh/kit-constants';
1
2
  const clampChannel = value => Math.min(255, Math.max(0, Math.round(value)));
2
3
  const parseHex = color => {
3
4
  const match = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(color);
@@ -21,7 +22,26 @@ const parseFunctional = color => {
21
22
  }
22
23
  return [parts[0], parts[1], parts[2], parts[3] === undefined ? 1 : parts[3]];
23
24
  };
24
- export const parseColor = color => parseHex(color.trim()) ?? parseFunctional(color.trim());
25
+ const TOKEN_OF_VALUE = new Map(Object.keys(Color).filter(token => token !== 'CURRENT').map(token => [Color[token], token]));
26
+ /** Theme the page is painted in; a chart reads it the way CSS does, off `<html>`. */
27
+ export const activeTheme = () => typeof document !== 'undefined' && document.documentElement.getAttribute(THEME_ATTRIBUTE) === 'dark' ? 'dark' : DEFAULT_THEME;
28
+ const unwrapVar = color => {
29
+ const match = /^var\(\s*--[^,)]+,([\s\S]+)\)$/.exec(color);
30
+ return match ? match[1].trim() : null;
31
+ };
32
+ /**
33
+ * Literal behind a design-system colour. Tokens are `var(--pw-color-x, <light hex>)`, whose fallback lies
34
+ * under a dark theme, so a token resolves through the palette and only an unknown `var()` takes its fallback.
35
+ */
36
+ const resolveColor = color => {
37
+ const token = TOKEN_OF_VALUE.get(color);
38
+ return token ? getThemeColors(activeTheme())[token] : unwrapVar(color);
39
+ };
40
+ export const parseColor = color => {
41
+ const value = color.trim();
42
+ const literal = resolveColor(value);
43
+ return literal !== null ? parseColor(literal) : parseHex(value) ?? parseFunctional(value);
44
+ };
25
45
  const toCss = ([r, g, b, a]) => a >= 1 ? `#${[r, g, b].map(channel => clampChannel(channel).toString(16).padStart(2, '0')).join('')}` : `rgba(${clampChannel(r)}, ${clampChannel(g)}, ${clampChannel(b)}, ${Number(a.toFixed(3))})`;
26
46
  const mix = (from, to, t) => [from[0] + (to[0] - from[0]) * t, from[1] + (to[1] - from[1]) * t, from[2] + (to[2] - from[2]) * t, from[3] + (to[3] - from[3]) * t];
27
47
  // A stop whose colour cannot be parsed still holds its position: it is returned
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@pushwoosh/kit-charts",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "Small React chart library on SVG, with a Highcharts-shaped configuration model",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://gitlab.corp.pushwoosh.com/frontend/development-kit/charts.git"
8
+ "url": "git+https://gitlab.corp.pushwoosh.com/frontend/frontend-monorepo.git",
9
+ "directory": "packages/charts"
9
10
  },
10
11
  "keywords": [
11
12
  "chart",
@@ -21,44 +22,48 @@
21
22
  "types": "index.d.ts",
22
23
  "sideEffects": false,
23
24
  "publishConfig": {
24
- "access": "public"
25
+ "access": "public",
26
+ "directory": "dist"
25
27
  },
26
- "scripts": {
27
- "start": "npm run playground",
28
- "build": "pushwoosh-engine lib:build && cp ai-documentation.md LICENSE dist/",
29
- "playground": "webpack serve --config ./node_modules/@pushwoosh/frontend-builder-engine/lib/webpack.playground.config.js --stats-error-details",
30
- "check": "npm run check:lint && npm run check:types",
31
- "check:lint": "echo \"Run check:lint\" && NODE_ENV=production eslint ./src ./playground ./tests",
32
- "check:lint-fix": "echo \"Run check:lint\" && NODE_ENV=production eslint ./src ./playground ./tests --fix",
33
- "check:types": "echo \"Run check:types\" && pushwoosh-engine lib:check-types && tsc --noEmit -p tsconfig.json",
34
- "test": "jest"
35
- },
36
- "pre-commit": "check",
37
28
  "dependencies": {
38
- "@pushwoosh/kit-constants": "^1.8.0"
29
+ "@pushwoosh/kit-constants": "^2.0.0"
39
30
  },
40
31
  "devDependencies": {
41
32
  "@pushwoosh/frontend-builder-engine": "^3.1.0",
33
+ "@testing-library/dom": "^10.4.2",
42
34
  "@testing-library/jest-dom": "^6.9.1",
43
35
  "@testing-library/react": "^16.3.0",
44
36
  "@types/jest": "^30.0.0",
45
- "@types/react": "^18.3.2",
46
- "@types/react-dom": "^18.3.0",
37
+ "@types/node": "^26.1.1",
38
+ "@types/react": "^18.3.31",
39
+ "@types/react-dom": "^18.3.7",
47
40
  "@types/styled-components": "^5.1.34",
48
- "cross-env": "^7.0.3",
49
41
  "jest": "^30.2.0",
50
42
  "jest-environment-jsdom": "^30.2.0",
51
- "pre-commit": "^1.2.2",
52
43
  "react": "^18.3.1",
53
44
  "react-dom": "^18.3.1",
54
45
  "styled-components": "^5.3.11",
55
- "ts-jest": "^29.4.6"
46
+ "ts-jest": "^29.4.6",
47
+ "typescript": "^6.0.3",
48
+ "webpack": "^5.94.0",
49
+ "webpack-cli": "^6.0.1",
50
+ "webpack-dev-server": "^5.0.4"
56
51
  },
57
52
  "peerDependencies": {
58
53
  "react": ">=18.0.0",
59
54
  "styled-components": ">=5.3.3"
60
55
  },
61
56
  "engines": {
62
- "node": ">= 18"
57
+ "node": ">= 24"
58
+ },
59
+ "scripts": {
60
+ "start": "pnpm run playground",
61
+ "build": "pushwoosh-engine lib:build && cp ai-documentation.md LICENSE dist/",
62
+ "playground": "webpack serve --config ./node_modules/@pushwoosh/frontend-builder-engine/lib/webpack.playground.config.js --stats-error-details",
63
+ "check": "pnpm run check:lint && pnpm run check:types",
64
+ "check:lint": "echo \"Run check:lint\" && NODE_ENV=production eslint ./src ./playground ./tests",
65
+ "check:lint-fix": "echo \"Run check:lint\" && NODE_ENV=production eslint ./src ./playground ./tests --fix",
66
+ "check:types": "echo \"Run check:types\" && pushwoosh-engine lib:check-types && tsc --noEmit -p tsconfig.json",
67
+ "test": "jest"
63
68
  }
64
- }
69
+ }