@rojaostudio/ds 2.0.0-next.22 → 2.0.0-next.23

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.
@@ -43,7 +43,8 @@ interface ChartProps extends Omit<HTMLAttributes<HTMLElement>, 'children' | 'onS
43
43
  showAllDates?: boolean;
44
44
  /**
45
45
  * bar and column: where each item leads, in the order of `labels`. In bar each bar becomes a link named
46
- * "<label>: <value>"; in column a click or Enter on the plot follows the item's link.
46
+ * "<label>: <value>"; in column a click or Enter on the plot follows the item's link. Only http(s) URLs, relative
47
+ * paths and #fragments are followed; any other scheme (javascript:, data:…) is ignored, with a warning in dev.
47
48
  */
48
49
  hrefs?: Array<string | undefined>;
49
50
  /** bar and column: called with the item's index when it is chosen (click, Enter). In bar each bar becomes a button. */
@@ -53,11 +54,6 @@ interface ChartProps extends Omit<HTMLAttributes<HTMLElement>, 'children' | 'onS
53
54
  /** Height of the plot area, in px (Figma: 200). */
54
55
  height?: number;
55
56
  }
56
- /**
57
- * Chart — Figma [RDS] Content/Chart. The chart area, to go inside a Card. Every chart carries a table with the same
58
- * data (visually hidden unless `showTable`). In line and column the plot is a slider for screen readers and the
59
- * keyboard: the arrows move from point to point, and each point is read with its label and values. Styles: chart.css.
60
- */
61
- declare function Chart({ label, type, labels, series, formatLeft, formatRight, showRightAxis, showLegend, showTooltip, dates, dateEvery, showAllDates, hrefs, onSelect, showTable, height, className, ...rest }: ChartProps): react.JSX.Element;
57
+ declare function Chart({ label, type, labels, series, formatLeft, formatRight, showRightAxis, showLegend, showTooltip, dates, dateEvery, showAllDates, hrefs: hrefsProp, onSelect, showTable, height, className, ...rest }: ChartProps): react.JSX.Element;
62
58
 
63
59
  export { Chart, type ChartProps, type ChartSeries, type ChartType };
@@ -5,7 +5,7 @@ import {
5
5
  __spreadValues
6
6
  } from "../chunk-ORMEWXMH.js";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { useId, useState } from "react";
8
+ import { useId, useMemo, useState } from "react";
9
9
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
10
10
  const compact = new Intl.NumberFormat("pt-BR", { notation: "compact", maximumFractionDigits: 1 });
11
11
  const defaultFormat = (value) => compact.format(value);
@@ -25,6 +25,20 @@ function scaleOf(values) {
25
25
  const max = min + step * 4;
26
26
  return { min, max, ticks: [4, 3, 2, 1, 0].map((i) => min + step * i) };
27
27
  }
28
+ const SAFE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
29
+ function safeHref(href) {
30
+ if (!href) return void 0;
31
+ if (href.startsWith("#")) return href;
32
+ try {
33
+ const base = typeof window !== "undefined" && SAFE_PROTOCOLS.has(window.location.protocol) ? window.location.href : "https://example.invalid/";
34
+ if (SAFE_PROTOCOLS.has(new URL(href, base).protocol)) return href;
35
+ } catch (e) {
36
+ }
37
+ if (process.env.NODE_ENV !== "production") {
38
+ console.warn(`Chart: href "${href}" ignored. Only http(s) URLs, relative paths and #fragments are followed.`);
39
+ }
40
+ return void 0;
41
+ }
28
42
  function Chart(_a) {
29
43
  var _b = _a, {
30
44
  label,
@@ -39,7 +53,7 @@ function Chart(_a) {
39
53
  dates,
40
54
  dateEvery,
41
55
  showAllDates,
42
- hrefs,
56
+ hrefs: hrefsProp,
43
57
  onSelect,
44
58
  showTable = false,
45
59
  height = 200,
@@ -65,6 +79,7 @@ function Chart(_a) {
65
79
  ]);
66
80
  var _a2;
67
81
  const [active, setActive] = useState(null);
82
+ const hrefs = useMemo(() => hrefsProp == null ? void 0 : hrefsProp.map(safeHref), [hrefsProp]);
68
83
  const tooltipId = useId();
69
84
  const count = labels.length;
70
85
  const shown = type === "bar" ? series.slice(0, 1) : series.slice(0, 5);
@@ -92,7 +107,10 @@ function Chart(_a) {
92
107
  const linked = type !== "line" && Boolean(onSelect || (hrefs == null ? void 0 : hrefs.some(Boolean)));
93
108
  const choose = (index) => {
94
109
  if (onSelect) onSelect(index);
95
- else if (hrefs == null ? void 0 : hrefs[index]) window.location.assign(hrefs[index]);
110
+ else {
111
+ const href = safeHref(hrefs == null ? void 0 : hrefs[index]);
112
+ if (href) window.location.assign(href);
113
+ }
96
114
  };
97
115
  const onPointerMove = (event) => {
98
116
  const box = event.currentTarget.getBoundingClientRect();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rojaostudio/ds",
3
- "version": "2.0.0-next.22",
3
+ "version": "2.0.0-next.23",
4
4
  "type": "module",
5
5
  "description": "Rojão Design System — componentes React, estilos e alvo React Native. O motor vive em @rojaostudio/ds-core.",
6
6
  "license": "MIT",
@@ -190,7 +190,7 @@
190
190
  "@radix-ui/react-toggle": "^1.1.18",
191
191
  "@radix-ui/react-toggle-group": "^1.1.19",
192
192
  "@radix-ui/react-tooltip": "^1.2.16",
193
- "@rojaostudio/ds-core": "1.1.0-next.8"
193
+ "@rojaostudio/ds-core": "1.1.0-next.9"
194
194
  },
195
195
  "scripts": {
196
196
  "build": "pnpm run build:tokens && pnpm run build:themes && pnpm run build:rds && pnpm run build:native && tsup",