@flux-ui/statistics 3.0.0-next.72 → 3.0.0-next.74

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.
Files changed (32) hide show
  1. package/dist/component/index.d.ts +1 -1
  2. package/dist/index.js +94 -76
  3. package/dist/index.js.map +1 -1
  4. package/dist/util/html.d.ts +9 -0
  5. package/dist/util/index.d.ts +1 -0
  6. package/dist/util/options/cartesian/buildCandlestickChartOptions.d.ts +1 -2
  7. package/dist/util/options/circular/buildGaugeChartOptions.d.ts +1 -2
  8. package/package.json +10 -10
  9. package/src/component/FluxStatisticsAreaChart.vue +1 -1
  10. package/src/component/FluxStatisticsBarChart.vue +1 -1
  11. package/src/component/FluxStatisticsBoxPlotChart.vue +1 -1
  12. package/src/component/FluxStatisticsBubbleChart.vue +1 -1
  13. package/src/component/FluxStatisticsCandlestickChart.vue +1 -1
  14. package/src/component/FluxStatisticsDonutChart.vue +1 -1
  15. package/src/component/FluxStatisticsHeatmapChart.vue +1 -1
  16. package/src/component/FluxStatisticsLineChart.vue +1 -1
  17. package/src/component/FluxStatisticsMixedChart.vue +1 -1
  18. package/src/component/FluxStatisticsPercentageBar.vue +1 -1
  19. package/src/component/FluxStatisticsPieChart.vue +1 -1
  20. package/src/component/FluxStatisticsPolarAreaChart.vue +1 -1
  21. package/src/component/FluxStatisticsRadarChart.vue +1 -1
  22. package/src/component/FluxStatisticsRadialBar.vue +1 -1
  23. package/src/component/FluxStatisticsScatterChart.vue +1 -1
  24. package/src/component/FluxStatisticsTreemapChart.vue +1 -1
  25. package/src/component/index.ts +1 -1
  26. package/src/index.ts +2 -2
  27. package/src/util/html.ts +25 -0
  28. package/src/util/icons.ts +3 -1
  29. package/src/util/index.ts +1 -0
  30. package/src/util/options/cartesian/buildCandlestickChartOptions.ts +1 -2
  31. package/src/util/options/circular/buildGaugeChartOptions.ts +1 -2
  32. package/src/util/tooltips/render.ts +7 -5
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Escapes a value for safe interpolation into HTML text content.
3
+ */
4
+ export declare function escapeHtml(value: unknown): string;
5
+ /**
6
+ * Escapes a value for safe interpolation into a double-quoted HTML attribute
7
+ * or inline style value. Prevents attribute breakout from untrusted input.
8
+ */
9
+ export declare function escapeAttr(value: unknown): string;
@@ -1,4 +1,5 @@
1
1
  export * from './colors';
2
+ export * from './html';
2
3
  export * from './icons';
3
4
  export * from './options';
4
5
  export * from './series';
@@ -1,6 +1,5 @@
1
1
  import { FluxStatisticsChartCandlestickSeries } from '@flux-ui/types';
2
- import { ChartLegendItem } from '../../../composable/useChartLegend';
3
- import { EChartsOption } from '../../../composable/useECharts';
2
+ import { ChartLegendItem, EChartsOption } from '../../../composable';
4
3
  import { TooltipStyleClasses, Translator } from '../../tooltips';
5
4
  export interface CandlestickChartOptionsInput {
6
5
  readonly series: readonly FluxStatisticsChartCandlestickSeries[];
@@ -1,6 +1,5 @@
1
1
  import { FluxStatisticsChartGaugeSeries } from '@flux-ui/types';
2
- import { ChartLegendItem } from '../../../composable/useChartLegend';
3
- import { EChartsOption } from '../../../composable/useECharts';
2
+ import { ChartLegendItem, EChartsOption } from '../../../composable';
4
3
  import { TooltipStyleClasses, Translator } from '../../tooltips';
5
4
  export interface GaugeChartOptionsInput {
6
5
  readonly series: readonly FluxStatisticsChartGaugeSeries[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@flux-ui/statistics",
3
3
  "description": "Statistics components for the Flux UI library.",
4
- "version": "3.0.0-next.72",
4
+ "version": "3.0.0-next.74",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/basmilius",
@@ -49,28 +49,28 @@
49
49
  "types": "./dist/index.d.ts",
50
50
  "sideEffects": false,
51
51
  "dependencies": {
52
- "@basmilius/common": "^3.37.0",
53
- "@basmilius/utils": "^3.37.0",
54
- "@flux-ui/components": "3.0.0-next.72",
55
- "@flux-ui/internals": "3.0.0-next.72",
56
- "@flux-ui/types": "3.0.0-next.72",
52
+ "@basmilius/common": "^3.40.0",
53
+ "@basmilius/utils": "^3.40.0",
54
+ "@flux-ui/components": "3.0.0-next.74",
55
+ "@flux-ui/internals": "3.0.0-next.74",
56
+ "@flux-ui/types": "3.0.0-next.74",
57
57
  "clsx": "^2.1.1"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "echarts": "^6.1.0",
61
61
  "lodash-es": "^4.18.1",
62
- "vue": "^3.6.0-beta.12",
62
+ "vue": "^3.6.0-beta.13",
63
63
  "vue-i18n": "^11.4.4"
64
64
  },
65
65
  "devDependencies": {
66
- "@basmilius/vite-preset": "^3.37.0",
66
+ "@basmilius/vite-preset": "^3.40.0",
67
67
  "@types/lodash-es": "^4.17.12",
68
68
  "@types/node": "^25.9.1",
69
69
  "@vitejs/plugin-vue": "^6.0.7",
70
70
  "@vue/tsconfig": "^0.9.1",
71
71
  "sass-embedded": "^1.100.0",
72
72
  "typescript": "^6.0.3",
73
- "vite": "^8.0.14",
74
- "vue-tsc": "^3.3.2"
73
+ "vite": "^8.0.16",
74
+ "vue-tsc": "^3.3.3"
75
75
  }
76
76
  }
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartAreaSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildAreaChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartBarSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildBarChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartBoxPlotSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildBoxPlotChartOptions } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartBubbleSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildBubbleChartOptions } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartCandlestickSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildCandlestickChartOptions, candlestickLegendItemBuilder } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSlicesSetup } from '~flux/statistics/composable';
13
13
  import { buildDonutChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -8,7 +8,7 @@
8
8
  setup>
9
9
  import type { FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
10
10
  import { computed } from 'vue';
11
- import { useChartBaseSetup, type EChartsOption } from '~flux/statistics/composable';
11
+ import { type EChartsOption, useChartBaseSetup } from '~flux/statistics/composable';
12
12
  import { buildHeatmapChartOptions } from '~flux/statistics/util';
13
13
  import Chart from './FluxStatisticsChart.vue';
14
14
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartLineSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildLineChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartMixedSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildMixedChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -36,7 +36,7 @@
36
36
  import type { FluxStatisticsChartColor, FluxStatisticsPercentageBarItemObject } from '@flux-ui/types';
37
37
  import { clsx } from 'clsx';
38
38
  import { computed, inject, watchEffect } from 'vue';
39
- import { FluxStatisticsChartLegendInjectionKey, type ChartLegendItem } from '~flux/statistics/composable';
39
+ import { type ChartLegendItem, FluxStatisticsChartLegendInjectionKey } from '~flux/statistics/composable';
40
40
  import $style from '~flux/statistics/css/PercentageBar.module.scss';
41
41
 
42
42
  const SEMANTIC_COLORS = ['gray', 'primary', 'danger', 'info', 'success', 'warning'] as const;
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSlicesSetup } from '~flux/statistics/composable';
13
13
  import { buildPieChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSlicesSetup } from '~flux/statistics/composable';
13
13
  import { buildPolarAreaChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartRadarIndicator, FluxStatisticsChartRadarSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildRadarChartOptions } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartGaugeSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildGaugeChartOptions, gaugeLegendItemBuilder } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -9,7 +9,7 @@
9
9
  setup>
10
10
  import type { FluxStatisticsChartScatterSeries } from '@flux-ui/types';
11
11
  import { computed } from 'vue';
12
- import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
12
+ import { type EChartsOption, useChartSeriesSetup } from '~flux/statistics/composable';
13
13
  import { buildScatterChartOptions } from '~flux/statistics/util';
14
14
  import Chart from './FluxStatisticsChart.vue';
15
15
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -8,7 +8,7 @@
8
8
  setup>
9
9
  import type { FluxStatisticsChartTreemapNode } from '@flux-ui/types';
10
10
  import { computed } from 'vue';
11
- import { useChartBaseSetup, type EChartsOption } from '~flux/statistics/composable';
11
+ import { type EChartsOption, useChartBaseSetup } from '~flux/statistics/composable';
12
12
  import { buildTreemapChartOptions } from '~flux/statistics/util';
13
13
  import Chart from './FluxStatisticsChart.vue';
14
14
  import $style from '~flux/statistics/css/Chart.module.scss';
@@ -14,8 +14,8 @@ export { default as FluxStatisticsDonutChart } from './FluxStatisticsDonutChart.
14
14
  export { default as FluxStatisticsEmpty } from './FluxStatisticsEmpty.vue';
15
15
  export { default as FluxStatisticsGrid } from './FluxStatisticsGrid.vue';
16
16
  export { default as FluxStatisticsHeatmapChart } from './FluxStatisticsHeatmapChart.vue';
17
- export { default as FluxStatisticsLineChart } from './FluxStatisticsLineChart.vue';
18
17
  export { default as FluxStatisticsKpi } from './FluxStatisticsKpi.vue';
18
+ export { default as FluxStatisticsLineChart } from './FluxStatisticsLineChart.vue';
19
19
  export { default as FluxStatisticsLegend } from './FluxStatisticsLegend.vue';
20
20
  export { default as FluxStatisticsLegendItem } from './FluxStatisticsLegendItem.vue';
21
21
  export { default as FluxStatisticsLegendScope } from './FluxStatisticsLegendScope.vue';
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { amber500, blue500, cyan500, emerald500, fuchsia500, green500, indigo500, lime500, orange500, pink500, purple500, red500, rose50, sky500, teal500, violet500, yellow500 } from '@flux-ui/internals';
1
+ import { amber500, blue500, cyan500, emerald500, fuchsia500, green500, indigo500, lime500, orange500, pink500, purple500, red500, rose500, sky500, teal500, violet500, yellow500 } from '@flux-ui/internals';
2
2
  import type { FluxStatisticsChartColor } from '@flux-ui/types';
3
3
 
4
4
  export * from './component';
@@ -30,5 +30,5 @@ export const CHART_COLORFUL_COLORS: readonly FluxStatisticsChartColor[] = [
30
30
  purple500,
31
31
  fuchsia500,
32
32
  pink500,
33
- rose50
33
+ rose500
34
34
  ] as FluxStatisticsChartColor[];
@@ -0,0 +1,25 @@
1
+ const HTML_ESCAPES: Record<string, string> = {
2
+ '&': '&amp;',
3
+ '<': '&lt;',
4
+ '>': '&gt;',
5
+ '"': '&quot;',
6
+ '\'': '&#39;'
7
+ };
8
+
9
+ const HTML_PATTERN = /[&<>"']/g;
10
+ const ATTR_PATTERN = /[&<>"]/g;
11
+
12
+ /**
13
+ * Escapes a value for safe interpolation into HTML text content.
14
+ */
15
+ export function escapeHtml(value: unknown): string {
16
+ return String(value ?? '').replace(HTML_PATTERN, char => HTML_ESCAPES[char]);
17
+ }
18
+
19
+ /**
20
+ * Escapes a value for safe interpolation into a double-quoted HTML attribute
21
+ * or inline style value. Prevents attribute breakout from untrusted input.
22
+ */
23
+ export function escapeAttr(value: unknown): string {
24
+ return String(value ?? '').replace(ATTR_PATTERN, char => HTML_ESCAPES[char]);
25
+ }
package/src/util/icons.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { iconRegistry } from '@flux-ui/components';
2
2
  import type { FluxIconName } from '@flux-ui/types';
3
+ import { escapeAttr } from './html';
3
4
 
4
5
  export function renderIconSvg(name: FluxIconName | undefined, color: string, size: number = 14): string {
5
6
  if (!name) {
@@ -14,7 +15,8 @@ export function renderIconSvg(name: FluxIconName | undefined, color: string, siz
14
15
 
15
16
  const [width, height, , , pathData] = icon;
16
17
  const paths = Array.isArray(pathData) ? pathData : [pathData];
17
- const pathElements = paths.map(d => `<path d="${d}" fill="${color}"/>`).join('');
18
+ const safeColor = escapeAttr(color);
19
+ const pathElements = paths.map(d => `<path d="${escapeAttr(d)}" fill="${safeColor}"/>`).join('');
18
20
 
19
21
  return `<svg viewBox="0 0 ${width} ${height}" width="${size}" height="${size}" focusable="false" aria-hidden="true">${pathElements}</svg>`;
20
22
  }
package/src/util/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './colors';
2
+ export * from './html';
2
3
  export * from './icons';
3
4
  export * from './options';
4
5
  export * from './series';
@@ -1,7 +1,6 @@
1
1
  import type { FluxStatisticsChartCandlestickSeries } from '@flux-ui/types';
2
2
  import { merge } from 'lodash-es';
3
- import type { ChartLegendItem } from '~flux/statistics/composable/useChartLegend';
4
- import type { EChartsOption } from '~flux/statistics/composable/useECharts';
3
+ import type { ChartLegendItem, EChartsOption } from '~flux/statistics/composable';
5
4
  import { resolveChartColor, toCandlestickSeries } from '../../series';
6
5
  import type { TooltipStyleClasses, Translator } from '../../tooltips';
7
6
  import { buildCartesianTooltip } from '../../tooltips';
@@ -1,7 +1,6 @@
1
1
  import type { FluxStatisticsChartGaugeSeries } from '@flux-ui/types';
2
2
  import { merge } from 'lodash-es';
3
- import type { ChartLegendItem } from '~flux/statistics/composable/useChartLegend';
4
- import type { EChartsOption } from '~flux/statistics/composable/useECharts';
3
+ import type { ChartLegendItem, EChartsOption } from '~flux/statistics/composable';
5
4
  import { toGaugeSeries } from '../../series';
6
5
  import type { TooltipStyleClasses, Translator } from '../../tooltips';
7
6
  import { buildGaugeTooltip } from '../../tooltips';
@@ -1,4 +1,5 @@
1
1
  import { formatNumber } from '@basmilius/utils';
2
+ import { escapeAttr, escapeHtml } from '../html';
2
3
  import { renderIconSvg } from '../icons';
3
4
  import type { ChartTooltipValueFormatter, SharedTooltipItem, TooltipParam, TooltipStyleClasses, Translator } from './types';
4
5
 
@@ -15,7 +16,7 @@ export function renderTooltip(
15
16
  }
16
17
 
17
18
  const titleHtml = title
18
- ? `<div class="${styles.statisticsChartTooltipTitle}">${title}</div>`
19
+ ? `<div class="${styles.statisticsChartTooltipTitle}">${escapeHtml(title)}</div>`
19
20
  : '';
20
21
 
21
22
  const hasActive = activeIndex !== -1;
@@ -25,16 +26,17 @@ export function renderTooltip(
25
26
  const activeClass = isActive ? ` ${styles.isActive}` : '';
26
27
  const translatedName = item.name ? t(String(item.name)) : '';
27
28
 
29
+ const safeColor = escapeAttr(item.color);
28
30
  const marker = item.icon
29
- ? `<div class="${styles.statisticsChartTooltipSeriesIcon}${activeClass}" style="color: ${item.color}">${renderIconSvg(item.icon, item.color, 14)}</div>`
30
- : `<div class="${styles.statisticsChartTooltipSeriesColor}${activeClass}" style="background: ${item.color}"></div>`;
31
+ ? `<div class="${styles.statisticsChartTooltipSeriesIcon}${activeClass}" style="color: ${safeColor}">${renderIconSvg(item.icon, item.color, 14)}</div>`
32
+ : `<div class="${styles.statisticsChartTooltipSeriesColor}${activeClass}" style="background: ${safeColor}"></div>`;
31
33
 
32
34
  const display = valueFormatter ? valueFormatter(item.value, item) : formatValue(item.value);
33
35
 
34
36
  return `
35
37
  ${marker}
36
- <div class="${styles.statisticsChartTooltipSeriesName}${activeClass}">${translatedName}</div>
37
- <div class="${styles.statisticsChartTooltipSeriesValue}${activeClass}">${display}</div>
38
+ <div class="${styles.statisticsChartTooltipSeriesName}${activeClass}">${escapeHtml(translatedName)}</div>
39
+ <div class="${styles.statisticsChartTooltipSeriesValue}${activeClass}">${escapeHtml(display)}</div>
38
40
  `;
39
41
  }).join('');
40
42