diff --git a/package.json b/package.json index ff26198..d683186 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cameleer/design-system", - "version": "0.1.45", + "version": "0.1.46", "type": "module", "main": "./dist/index.es.js", "module": "./dist/index.es.js", diff --git a/src/design-system/composites/AreaChart/AreaChart.module.css b/src/design-system/composites/AreaChart/AreaChart.module.css index f9199e1..b36f8ca 100644 --- a/src/design-system/composites/AreaChart/AreaChart.module.css +++ b/src/design-system/composites/AreaChart/AreaChart.module.css @@ -1,8 +1,9 @@ .wrapper { position: relative; - display: inline-flex; + display: flex; flex-direction: column; gap: 4px; + width: 100%; } .svg { @@ -78,6 +79,15 @@ white-space: nowrap; } +.tooltipTime { + font-family: var(--font-mono); + font-size: 10px; + color: var(--text-muted); + margin-bottom: 4px; + padding-bottom: 3px; + border-bottom: 1px solid var(--border-subtle); +} + .tooltipRow { display: flex; align-items: center; diff --git a/src/design-system/composites/AreaChart/AreaChart.tsx b/src/design-system/composites/AreaChart/AreaChart.tsx index e3ea506..6f0f54f 100644 --- a/src/design-system/composites/AreaChart/AreaChart.tsx +++ b/src/design-system/composites/AreaChart/AreaChart.tsx @@ -45,6 +45,7 @@ export function AreaChart({ const [tooltip, setTooltip] = useState<{ x: number y: number + xLabel: string values: { label: string; value: number; color: string }[] } | null>(null) @@ -84,6 +85,15 @@ export function AreaChart({ // Find closest x value const pctX = (mx - dims.paddingLeft) / plotW + const firstS = series[0] + const idx0 = Math.max(0, Math.min(firstS.data.length - 1, Math.round(pctX * (firstS.data.length - 1)))) + const xVal = firstS.data[idx0]?.x + const xLabel = xVal instanceof Date + ? xVal.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }) + : typeof xVal === 'number' && xVal > 1e10 + ? new Date(xVal).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }) + : String(xVal ?? '') + const values = series.map((s, i) => { const idx = Math.round(pctX * (s.data.length - 1)) const clamped = Math.max(0, Math.min(s.data.length - 1, idx)) @@ -95,16 +105,17 @@ export function AreaChart({ } }) - setTooltip({ x: mx, y: my, values }) + setTooltip({ x: mx, y: my, xLabel, values }) } return (
{yLabel &&
{yLabel}
} setTooltip(null)} @@ -223,6 +234,9 @@ export function AreaChart({ top: tooltip.y, }} > + {tooltip.xLabel && ( +
{tooltip.xLabel}
+ )} {tooltip.values.map((v) => (
diff --git a/src/design-system/composites/BarChart/BarChart.module.css b/src/design-system/composites/BarChart/BarChart.module.css index 4248039..61b1683 100644 --- a/src/design-system/composites/BarChart/BarChart.module.css +++ b/src/design-system/composites/BarChart/BarChart.module.css @@ -1,8 +1,9 @@ .wrapper { position: relative; - display: inline-flex; + display: flex; flex-direction: column; gap: 4px; + width: 100%; } .svg { diff --git a/src/design-system/composites/BarChart/BarChart.tsx b/src/design-system/composites/BarChart/BarChart.tsx index 3e6f852..a1e114a 100644 --- a/src/design-system/composites/BarChart/BarChart.tsx +++ b/src/design-system/composites/BarChart/BarChart.tsx @@ -101,9 +101,10 @@ export function BarChart({
{yLabel &&
{yLabel}
} setTooltip(null)} aria-label="Bar chart" diff --git a/src/design-system/composites/LineChart/LineChart.module.css b/src/design-system/composites/LineChart/LineChart.module.css index 1a63ad9..89f76af 100644 --- a/src/design-system/composites/LineChart/LineChart.module.css +++ b/src/design-system/composites/LineChart/LineChart.module.css @@ -1,8 +1,9 @@ .wrapper { position: relative; - display: inline-flex; + display: flex; flex-direction: column; gap: 4px; + width: 100%; } .svg { @@ -69,6 +70,15 @@ white-space: nowrap; } +.tooltipTime { + font-family: var(--font-mono); + font-size: 10px; + color: var(--text-muted); + margin-bottom: 4px; + padding-bottom: 3px; + border-bottom: 1px solid var(--border-subtle); +} + .tooltipRow { display: flex; align-items: center; diff --git a/src/design-system/composites/LineChart/LineChart.tsx b/src/design-system/composites/LineChart/LineChart.tsx index e9a12d1..96f5c60 100644 --- a/src/design-system/composites/LineChart/LineChart.tsx +++ b/src/design-system/composites/LineChart/LineChart.tsx @@ -44,6 +44,7 @@ export function LineChart({ const [tooltip, setTooltip] = useState<{ x: number y: number + xLabel: string values: { label: string; value: number; color: string }[] } | null>(null) @@ -80,6 +81,15 @@ export function LineChart({ const my = e.clientY - rect.top const pctX = (mx - dims.paddingLeft) / plotW + const firstS = series[0] + const idx0 = Math.max(0, Math.min(firstS.data.length - 1, Math.round(pctX * (firstS.data.length - 1)))) + const xVal = firstS.data[idx0]?.x + const xLabel = xVal instanceof Date + ? xVal.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }) + : typeof xVal === 'number' && xVal > 1e10 + ? new Date(xVal).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }) + : String(xVal ?? '') + const values = series.map((s, i) => { const idx = Math.round(pctX * (s.data.length - 1)) const clamped = Math.max(0, Math.min(s.data.length - 1, idx)) @@ -91,16 +101,17 @@ export function LineChart({ } }) - setTooltip({ x: mx, y: my, values }) + setTooltip({ x: mx, y: my, xLabel, values }) } return (
{yLabel &&
{yLabel}
} setTooltip(null)} @@ -202,6 +213,9 @@ export function LineChart({ className={styles.tooltip} style={{ left: tooltip.x + 12, top: tooltip.y }} > + {tooltip.xLabel && ( +
{tooltip.xLabel}
+ )} {tooltip.values.map((v) => (