@design.estate/dees-catalog 3.55.4 → 3.55.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-catalog",
3
- "version": "3.55.4",
3
+ "version": "3.55.6",
4
4
  "private": false,
5
5
  "description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
6
6
  "main": "dist_ts_web/index.js",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '3.55.4',
6
+ version: '3.55.6',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  }
@@ -8,7 +8,7 @@ import { DeesChartEchartsBase } from '../dees-chart-echarts-base.js';
8
8
  import { demoFunc } from './demo.js';
9
9
  import { barStyles } from './styles.js';
10
10
  import { renderChartBar } from './template.js';
11
- import { getEchartsSeriesColors, getThemeColors } from '../dees-chart-echarts-theme.js';
11
+ import { getEchartsSeriesColors, getThemeColors, hexToRgba } from '../dees-chart-echarts-theme.js';
12
12
 
13
13
  export interface IBarSeriesItem {
14
14
  name: string;
@@ -87,28 +87,42 @@ export class DeesChartBar extends DeesChartEchartsBase {
87
87
  splitLine: { lineStyle: { color: colors.borderSubtle } },
88
88
  };
89
89
 
90
- const seriesData = this.series.map((s, index) => ({
91
- name: s.name,
92
- type: 'bar' as const,
93
- data: s.data,
94
- stack: this.stacked ? 'total' : undefined,
95
- itemStyle: {
96
- color: s.color || seriesColors[index % seriesColors.length],
97
- borderRadius: this.stacked ? [0, 0, 0, 0] : this.horizontal ? [0, 4, 4, 0] : [4, 4, 0, 0],
98
- },
99
- barMaxWidth: 40,
100
- emphasis: {
90
+ const fillAlpha = this.goBright ? 0.15 : 0.25;
91
+ const borderRadius = this.horizontal ? [0, 4, 4, 0] : [4, 4, 0, 0];
92
+ const noBorderRadius = [0, 0, 0, 0];
93
+
94
+ const legendData: Array<{ name: string; itemStyle: { color: string } }> = [];
95
+
96
+ const seriesData = this.series.map((s, index) => {
97
+ const color = s.color || seriesColors[index % seriesColors.length];
98
+ legendData.push({ name: s.name, itemStyle: { color } });
99
+ return {
100
+ name: s.name,
101
+ type: 'bar' as const,
102
+ data: s.data,
103
+ stack: this.stacked ? 'total' : undefined,
101
104
  itemStyle: {
102
- shadowBlur: 6,
103
- shadowColor: 'rgba(0, 0, 0, 0.15)',
105
+ color: hexToRgba(color, fillAlpha),
106
+ borderColor: color,
107
+ borderWidth: 1,
108
+ borderRadius: this.stacked ? noBorderRadius : borderRadius,
104
109
  },
105
- },
106
- }));
110
+ barMaxWidth: 40,
111
+ barGap: '20%',
112
+ emphasis: {
113
+ itemStyle: {
114
+ color: hexToRgba(color, fillAlpha + 0.15),
115
+ borderColor: color,
116
+ borderWidth: 1.5,
117
+ },
118
+ },
119
+ };
120
+ });
107
121
 
108
122
  // For stacked bars, round the top corners of the last visible series
109
123
  if (this.stacked && seriesData.length > 0) {
110
124
  const last = seriesData[seriesData.length - 1];
111
- last.itemStyle.borderRadius = this.horizontal ? [0, 4, 4, 0] : [4, 4, 0, 0];
125
+ last.itemStyle.borderRadius = borderRadius;
112
126
  }
113
127
 
114
128
  return {
@@ -119,13 +133,15 @@ export class DeesChartBar extends DeesChartEchartsBase {
119
133
  const items = Array.isArray(params) ? params : [params];
120
134
  let result = `<strong>${items[0].axisValueLabel}</strong><br/>`;
121
135
  for (const p of items) {
122
- result += `${p.marker} ${p.seriesName}: <strong>${formatter(p.value)}</strong><br/>`;
136
+ const solidColor = p.borderColor || p.color;
137
+ const marker = `<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${solidColor};"></span>`;
138
+ result += `${marker}${p.seriesName}: <strong>${formatter(p.value)}</strong><br/>`;
123
139
  }
124
140
  return result;
125
141
  },
126
142
  },
127
143
  legend: this.showLegend && this.series.length > 1
128
- ? { bottom: 8, itemWidth: 10, itemHeight: 10 }
144
+ ? { bottom: 8, itemWidth: 10, itemHeight: 10, data: legendData }
129
145
  : { show: false },
130
146
  grid: {
131
147
  left: 16,
@@ -8,7 +8,7 @@ import { DeesChartEchartsBase } from '../dees-chart-echarts-base.js';
8
8
  import { demoFunc } from './demo.js';
9
9
  import { donutStyles } from './styles.js';
10
10
  import { renderChartDonut } from './template.js';
11
- import { getEchartsSeriesColors, getThemeColors } from '../dees-chart-echarts-theme.js';
11
+ import { getEchartsSeriesColors, getThemeColors, hexToRgba } from '../dees-chart-echarts-theme.js';
12
12
 
13
13
  export interface IDonutDataItem {
14
14
  name: string;
@@ -62,13 +62,32 @@ export class DeesChartDonut extends DeesChartEchartsBase {
62
62
  }
63
63
 
64
64
  protected buildOption(): Record<string, any> {
65
- const colors = getThemeColors(this.goBright);
65
+ const themeColors = getThemeColors(this.goBright);
66
66
  const seriesColors = getEchartsSeriesColors(this.goBright);
67
- const data = this.data.map((item, index) => ({
68
- name: item.name,
69
- value: item.value,
70
- itemStyle: item.color ? { color: item.color } : { color: seriesColors[index % seriesColors.length] },
71
- }));
67
+ const fillAlpha = this.goBright ? 0.15 : 0.2;
68
+
69
+ const legendData: Array<{ name: string; itemStyle: { color: string } }> = [];
70
+
71
+ const data = this.data.map((item, index) => {
72
+ const color = item.color || seriesColors[index % seriesColors.length];
73
+ legendData.push({ name: item.name, itemStyle: { color } });
74
+ return {
75
+ name: item.name,
76
+ value: item.value,
77
+ itemStyle: {
78
+ color: hexToRgba(color, fillAlpha),
79
+ borderColor: color,
80
+ borderWidth: 1,
81
+ },
82
+ emphasis: {
83
+ itemStyle: {
84
+ color: hexToRgba(color, fillAlpha + 0.15),
85
+ borderColor: color,
86
+ borderWidth: 1.5,
87
+ },
88
+ },
89
+ };
90
+ });
72
91
 
73
92
  const formatter = this.valueFormatter;
74
93
 
@@ -76,7 +95,9 @@ export class DeesChartDonut extends DeesChartEchartsBase {
76
95
  tooltip: {
77
96
  trigger: 'item',
78
97
  formatter: (params: any) => {
79
- return `${params.marker} ${params.name}: <strong>${formatter(params.value)}</strong> (${params.percent}%)`;
98
+ const solidColor = params.data?.itemStyle?.borderColor || params.color;
99
+ const marker = `<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${solidColor};"></span>`;
100
+ return `${marker}${params.name}: <strong>${formatter(params.value)}</strong> (${params.percent}%)`;
80
101
  },
81
102
  },
82
103
  legend: this.showLegend
@@ -87,6 +108,7 @@ export class DeesChartDonut extends DeesChartEchartsBase {
87
108
  itemWidth: 10,
88
109
  itemHeight: 10,
89
110
  itemGap: 12,
111
+ data: legendData,
90
112
  formatter: (name: string) => {
91
113
  const item = this.data.find((d) => d.name === name);
92
114
  return item ? `${name} ${formatter(item.value)}` : name;
@@ -99,31 +121,19 @@ export class DeesChartDonut extends DeesChartEchartsBase {
99
121
  radius: [this.innerRadiusPercent, '85%'],
100
122
  center: this.showLegend ? ['35%', '50%'] : ['50%', '50%'],
101
123
  avoidLabelOverlap: true,
124
+ padAngle: 2,
102
125
  itemStyle: {
103
126
  borderRadius: 4,
104
- borderColor: 'transparent',
105
- borderWidth: 2,
106
127
  },
107
128
  label: this.showLabels
108
129
  ? {
109
130
  show: true,
110
131
  formatter: '{b}: {d}%',
111
132
  fontSize: 11,
112
- color: colors.textSecondary,
133
+ color: themeColors.textSecondary,
113
134
  textBorderColor: 'transparent',
114
135
  }
115
136
  : { show: false },
116
- emphasis: {
117
- itemStyle: {
118
- shadowBlur: 10,
119
- shadowOffsetX: 0,
120
- shadowColor: 'rgba(0, 0, 0, 0.2)',
121
- },
122
- label: {
123
- show: true,
124
- fontWeight: 'bold',
125
- },
126
- },
127
137
  data,
128
138
  },
129
139
  ],
@@ -7,5 +7,8 @@ export const donutStyles = [
7
7
  :host {
8
8
  height: 360px;
9
9
  }
10
+ .chartContainer {
11
+ inset: 12px 0;
12
+ }
10
13
  `,
11
14
  ];
@@ -62,7 +62,7 @@ export abstract class DeesChartEchartsBase extends DeesElement {
62
62
  if (!chartContainer) return;
63
63
 
64
64
  try {
65
- this.chartInstance = this.echartsBundle.init(chartContainer);
65
+ this.chartInstance = this.echartsBundle.init(chartContainer, null, { renderer: 'svg' });
66
66
  this.updateChart();
67
67
 
68
68
  this.resizeObserver = new ResizeObserver(() => {
@@ -87,12 +87,17 @@ export abstract class DeesChartEchartsBase extends DeesElement {
87
87
  if (!this.chartInstance) return;
88
88
  const themeOptions = getEchartsThemeOptions(this.goBright);
89
89
  const chartOption = this.buildOption();
90
- // Merge theme defaults with chart-specific options
90
+ // Deep-merge theme defaults with chart-specific options for nested objects
91
91
  const merged = {
92
92
  ...themeOptions,
93
93
  ...chartOption,
94
94
  textStyle: { ...themeOptions.textStyle, ...(chartOption.textStyle || {}) },
95
95
  tooltip: { ...themeOptions.tooltip, ...(chartOption.tooltip || {}) },
96
+ legend: {
97
+ ...themeOptions.legend,
98
+ ...(chartOption.legend || {}),
99
+ textStyle: { ...(themeOptions.legend?.textStyle || {}), ...(chartOption.legend?.textStyle || {}) },
100
+ },
96
101
  };
97
102
  this.chartInstance.setOption(merged, true);
98
103
  }
@@ -3,8 +3,12 @@
3
3
  * Uses the centralized themeDefaults tokens so chart colors stay in sync
4
4
  * with the rest of the dees-catalog design system.
5
5
  *
6
- * ECharts renders on <canvas> and cannot read CSS custom properties,
6
+ * ECharts renders on <svg> and cannot read CSS custom properties,
7
7
  * so we reference the TypeScript source-of-truth (themeDefaults) directly.
8
+ *
9
+ * IMPORTANT: All colors passed to ECharts for data series must be hex or rgb/rgba.
10
+ * ECharts cannot interpolate HSL strings during hover/emphasis animations,
11
+ * causing them to flash black.
8
12
  */
9
13
 
10
14
  import { themeDefaults } from '../00theme.js';
@@ -12,22 +16,27 @@ import { themeDefaults } from '../00theme.js';
12
16
  const light = themeDefaults.colors.light;
13
17
  const dark = themeDefaults.colors.dark;
14
18
 
19
+ /**
20
+ * Series color palette for ECharts charts.
21
+ * Aligned with the Tailwind/shadcn-inspired palette used throughout the codebase.
22
+ * All values are hex — ECharts requires this for animation interpolation.
23
+ */
15
24
  const SERIES_COLORS = {
16
25
  dark: [
17
- dark.accentPrimary, // blue
18
- 'hsl(173.4 80.4% 40%)', // teal (no token yet)
19
- 'hsl(280.3 87.4% 66.7%)', // purple (no token yet)
20
- dark.accentWarning, // orange/amber
21
- dark.accentSuccess, // green
22
- dark.accentError, // rose/red
26
+ '#60a5fa', // blue-400 — softer in dark mode
27
+ '#2dd4bf', // teal-400
28
+ '#a78bfa', // violet-400
29
+ '#fbbf24', // amber-400
30
+ '#34d399', // emerald-400
31
+ '#fb7185', // rose-400
23
32
  ],
24
33
  light: [
25
- light.accentPrimary,
26
- 'hsl(142.1 76.2% 36.3%)', // teal (no token yet)
27
- 'hsl(280.3 47.7% 50.2%)', // purple (no token yet)
28
- light.accentWarning,
29
- light.accentSuccess,
30
- light.accentError,
34
+ '#3b82f6', // blue-500
35
+ '#14b8a6', // teal-500
36
+ '#8b5cf6', // violet-500
37
+ '#f59e0b', // amber-500
38
+ '#10b981', // emerald-500
39
+ '#f43f5e', // rose-500
31
40
  ],
32
41
  };
33
42
 
@@ -35,6 +44,16 @@ export function getEchartsSeriesColors(goBright: boolean): string[] {
35
44
  return goBright ? SERIES_COLORS.light : SERIES_COLORS.dark;
36
45
  }
37
46
 
47
+ /**
48
+ * Convert a hex color to an rgba string with the given alpha.
49
+ */
50
+ export function hexToRgba(hex: string, alpha: number): string {
51
+ const r = parseInt(hex.slice(1, 3), 16);
52
+ const g = parseInt(hex.slice(3, 5), 16);
53
+ const b = parseInt(hex.slice(5, 7), 16);
54
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
55
+ }
56
+
38
57
  export function getEchartsThemeOptions(goBright: boolean): Record<string, any> {
39
58
  const colors = goBright ? light : dark;
40
59
  return {
@@ -44,7 +63,8 @@ export function getEchartsThemeOptions(goBright: boolean): Record<string, any> {
44
63
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
45
64
  fontSize: 12,
46
65
  },
47
- color: goBright ? SERIES_COLORS.light : SERIES_COLORS.dark,
66
+ // No global `color` array each component sets per-item/per-series
67
+ // colors explicitly to avoid conflicts during emphasis animations.
48
68
  tooltip: {
49
69
  backgroundColor: colors.bgPrimary,
50
70
  borderColor: colors.borderDefault,
@@ -65,7 +85,6 @@ export function getEchartsThemeOptions(goBright: boolean): Record<string, any> {
65
85
 
66
86
  /**
67
87
  * Helper to get the resolved theme colors object for use in buildOption().
68
- * Components can use this instead of hardcoding dark/light color values.
69
88
  */
70
89
  export function getThemeColors(goBright: boolean) {
71
90
  return goBright ? light : dark;
@@ -8,7 +8,7 @@ import { DeesChartEchartsBase } from '../dees-chart-echarts-base.js';
8
8
  import { demoFunc } from './demo.js';
9
9
  import { radarStyles } from './styles.js';
10
10
  import { renderChartRadar } from './template.js';
11
- import { getEchartsSeriesColors, getThemeColors } from '../dees-chart-echarts-theme.js';
11
+ import { getEchartsSeriesColors, getThemeColors, hexToRgba } from '../dees-chart-echarts-theme.js';
12
12
 
13
13
  export interface IRadarIndicator {
14
14
  name: string;
@@ -67,16 +67,18 @@ export class DeesChartRadar extends DeesChartEchartsBase {
67
67
  const colors = getThemeColors(this.goBright);
68
68
  const seriesColors = getEchartsSeriesColors(this.goBright);
69
69
 
70
+ const fillAlpha = this.goBright ? 0.1 : 0.15;
71
+
70
72
  const seriesData = this.series.map((s, index) => {
71
73
  const color = s.color || seriesColors[index % seriesColors.length];
72
74
  return {
73
75
  name: s.name,
74
76
  value: s.values,
75
- itemStyle: { color },
76
- lineStyle: { color, width: 2 },
77
- areaStyle: this.fillArea ? { color, opacity: 0.15 } : undefined,
77
+ itemStyle: { color, borderColor: color, borderWidth: 1 },
78
+ lineStyle: { color, width: 1.5 },
79
+ areaStyle: this.fillArea ? { color: hexToRgba(color, fillAlpha) } : undefined,
78
80
  symbol: 'circle',
79
- symbolSize: 6,
81
+ symbolSize: 5,
80
82
  };
81
83
  });
82
84
 
@@ -56,7 +56,7 @@ export class DeesHeading extends DeesElement {
56
56
  align-items: center;
57
57
  text-align: center;
58
58
  margin: 16px 0;
59
- color: ${cssManager.bdTheme('#000', '#fff')};
59
+ color: ${cssManager.bdTheme('#999', '#555')};
60
60
  }
61
61
  /* Fade lines toward and away from text for hr style */
62
62
  .heading-hr::before {