@vielzeug/prism 26.10.3 → 26.10.4

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 (95) hide show
  1. package/README.md +1 -1
  2. package/dist/animation/easing.cjs +1 -1
  3. package/dist/animation/easing.cjs.map +1 -1
  4. package/dist/animation/easing.d.ts +15 -1
  5. package/dist/animation/easing.d.ts.map +1 -1
  6. package/dist/animation/easing.js +1 -1
  7. package/dist/animation/easing.js.map +1 -1
  8. package/dist/animation/motion.cjs +1 -1
  9. package/dist/animation/motion.cjs.map +1 -1
  10. package/dist/animation/motion.d.ts +17 -2
  11. package/dist/animation/motion.d.ts.map +1 -1
  12. package/dist/animation/motion.js +1 -1
  13. package/dist/animation/motion.js.map +1 -1
  14. package/dist/charts/area/area-chart.cjs +1 -1
  15. package/dist/charts/area/area-chart.cjs.map +1 -1
  16. package/dist/charts/area/area-chart.d.ts.map +1 -1
  17. package/dist/charts/area/area-chart.js +1 -1
  18. package/dist/charts/area/area-chart.js.map +1 -1
  19. package/dist/charts/area/area-renderer.cjs +1 -1
  20. package/dist/charts/area/area-renderer.cjs.map +1 -1
  21. package/dist/charts/area/area-renderer.d.ts +2 -2
  22. package/dist/charts/area/area-renderer.d.ts.map +1 -1
  23. package/dist/charts/area/area-renderer.js +1 -1
  24. package/dist/charts/area/area-renderer.js.map +1 -1
  25. package/dist/charts/bar/bar-chart.cjs +1 -1
  26. package/dist/charts/bar/bar-chart.cjs.map +1 -1
  27. package/dist/charts/bar/bar-chart.d.ts.map +1 -1
  28. package/dist/charts/bar/bar-chart.js +1 -1
  29. package/dist/charts/bar/bar-chart.js.map +1 -1
  30. package/dist/charts/bar/bar-renderer.cjs +1 -1
  31. package/dist/charts/bar/bar-renderer.cjs.map +1 -1
  32. package/dist/charts/bar/bar-renderer.d.ts +2 -2
  33. package/dist/charts/bar/bar-renderer.d.ts.map +1 -1
  34. package/dist/charts/bar/bar-renderer.js +1 -1
  35. package/dist/charts/bar/bar-renderer.js.map +1 -1
  36. package/dist/charts/line/line-chart.cjs +1 -1
  37. package/dist/charts/line/line-chart.cjs.map +1 -1
  38. package/dist/charts/line/line-chart.d.ts.map +1 -1
  39. package/dist/charts/line/line-chart.js +1 -1
  40. package/dist/charts/line/line-chart.js.map +1 -1
  41. package/dist/charts/line/line-renderer.cjs +1 -1
  42. package/dist/charts/line/line-renderer.cjs.map +1 -1
  43. package/dist/charts/line/line-renderer.d.ts +4 -2
  44. package/dist/charts/line/line-renderer.d.ts.map +1 -1
  45. package/dist/charts/line/line-renderer.js +1 -1
  46. package/dist/charts/line/line-renderer.js.map +1 -1
  47. package/dist/charts/pie/pie-chart.cjs +1 -1
  48. package/dist/charts/pie/pie-chart.cjs.map +1 -1
  49. package/dist/charts/pie/pie-chart.d.ts.map +1 -1
  50. package/dist/charts/pie/pie-chart.js +1 -1
  51. package/dist/charts/pie/pie-chart.js.map +1 -1
  52. package/dist/charts/radar/radar-chart.cjs +1 -1
  53. package/dist/charts/radar/radar-chart.cjs.map +1 -1
  54. package/dist/charts/radar/radar-chart.d.ts.map +1 -1
  55. package/dist/charts/radar/radar-chart.js +1 -1
  56. package/dist/charts/radar/radar-chart.js.map +1 -1
  57. package/dist/charts/sparkline/sparkline.cjs +1 -1
  58. package/dist/charts/sparkline/sparkline.cjs.map +1 -1
  59. package/dist/charts/sparkline/sparkline.d.ts.map +1 -1
  60. package/dist/charts/sparkline/sparkline.js +1 -1
  61. package/dist/charts/sparkline/sparkline.js.map +1 -1
  62. package/dist/core/responsive.cjs +1 -1
  63. package/dist/core/responsive.cjs.map +1 -1
  64. package/dist/core/responsive.d.ts.map +1 -1
  65. package/dist/core/responsive.js +1 -1
  66. package/dist/core/responsive.js.map +1 -1
  67. package/dist/index.d.ts +2 -2
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/interaction/crosshair.cjs +1 -1
  70. package/dist/interaction/crosshair.cjs.map +1 -1
  71. package/dist/interaction/crosshair.d.ts +7 -0
  72. package/dist/interaction/crosshair.d.ts.map +1 -1
  73. package/dist/interaction/crosshair.js +1 -1
  74. package/dist/interaction/crosshair.js.map +1 -1
  75. package/dist/interaction/tooltip.cjs +1 -1
  76. package/dist/interaction/tooltip.cjs.map +1 -1
  77. package/dist/interaction/tooltip.d.ts.map +1 -1
  78. package/dist/interaction/tooltip.js +1 -1
  79. package/dist/interaction/tooltip.js.map +1 -1
  80. package/dist/prism.cjs +1 -1
  81. package/dist/prism.cjs.map +1 -1
  82. package/dist/prism.iife.js +1 -1
  83. package/dist/prism.iife.js.map +1 -1
  84. package/dist/prism.js +1 -1
  85. package/dist/prism.js.map +1 -1
  86. package/dist/theme/index.cjs +1 -1
  87. package/dist/theme/index.cjs.map +1 -1
  88. package/dist/theme/index.d.ts +9 -4
  89. package/dist/theme/index.d.ts.map +1 -1
  90. package/dist/theme/index.js +1 -1
  91. package/dist/theme/index.js.map +1 -1
  92. package/dist/theme/prism.css +18 -4
  93. package/dist/types.d.ts +39 -5
  94. package/dist/types.d.ts.map +1 -1
  95. package/package.json +3 -6
@@ -1 +1 @@
1
- {"version":3,"file":"sparkline.js","names":[],"sources":["../../../src/charts/sparkline/sparkline.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { createTappers } from '../../_tappers';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport { createChartBase } from '../../core/chart-base';\nimport { uniqueId } from '../../core/ids';\nimport { PrismRenderError } from '../../errors';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ChartHandle, PrismEvent, SparklineConfig, StackSegment } from '../../types';\n\n/** Fits the 3.5px hover marker plus its ring inside the SVG. */\nconst PLOT_INSET = 5;\n\nfunction buildTopPoints(data: number[], width: number, height: number): Point[] {\n if (data.length === 0) return [];\n\n const xStep = width / Math.max(1, data.length - 1);\n const min = Math.min(...data);\n const max = Math.max(...data);\n const yRange = max - min || 1;\n\n return data.map((v, i) => ({\n x: i * xStep,\n y: height - ((v - min) / yRange) * height,\n }));\n}\n\nfunction buildAreaPath(\n data: number[],\n width: number,\n height: number,\n curve: SparklineConfig['curve'] = 'linear',\n): string {\n if (data.length === 0) return '';\n\n const top = buildTopPoints(data, width, height);\n const bottom = top.map((p) => ({ x: p.x, y: height }));\n\n return areaPath(top, bottom, curve ?? 'linear');\n}\n\nfunction buildPath(data: number[], width: number, height: number, curve: SparklineConfig['curve']): string {\n if (data.length === 0) return '';\n\n const points = buildTopPoints(data, width, height);\n\n return curve === 'monotone' ? monotonePath(points) : curve === 'step' ? stepPath(points) : linePath(points);\n}\n\nfunction renderSparkBars(\n parent: SVGGElement,\n data: number[],\n width: number,\n height: number,\n color: string,\n transition?: SparklineConfig['transition'],\n disposalSignal?: AbortSignal,\n): void {\n const count = data.length;\n const barW = Math.max(1, width / count - 1);\n const gap = width / count;\n const min = Math.min(0, ...data);\n const max = Math.max(...data);\n const yRange = max - min || 1;\n const motion = resolveMotion(transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n while (parent.children.length > count) {\n const last = parent.lastElementChild;\n\n if (last) parent.removeChild(last);\n }\n\n for (let i = 0; i < count; i++) {\n const finalH = Math.max(1, ((data[i] - min) / yRange) * height);\n const finalY = height - finalH;\n\n let rect = parent.children[i] as SVGRectElement | undefined;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-spark-bar' });\n parent.appendChild(rect);\n }\n\n setAttributes(rect, { fill: color, width: barW, x: i * gap });\n\n if (dur > 0 && !rect.hasAttribute('data-init')) {\n rect.setAttribute('data-init', '1');\n\n startTween({\n count: 1,\n duration: dur,\n easing,\n onFrame: (progress) => {\n const t = progress(0);\n\n setAttributes(rect!, {\n height: tweenNumber(0, finalH, t),\n y: tweenNumber(height, finalY, t),\n });\n },\n signal: disposalSignal,\n });\n } else {\n rect.setAttribute('data-init', '1');\n setAttributes(rect, { height: finalH, y: finalY });\n }\n }\n}\n\nfunction isStackData(data: number[] | StackSegment[]): data is StackSegment[] {\n return data.length > 0 && data[0] !== null && typeof data[0] === 'object';\n}\n\nfunction buildRoundedStackRect(\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n roundLeft: boolean,\n roundRight: boolean,\n): string {\n const maxR = Math.min(r, w / 2, h / 2);\n const tl = roundLeft ? maxR : 0;\n const bl = roundLeft ? maxR : 0;\n const tr = roundRight ? maxR : 0;\n const br = roundRight ? maxR : 0;\n\n return [\n `M${x + tl},${y}`,\n `H${x + w - tr}`,\n tr ? `Q${x + w},${y} ${x + w},${y + tr}` : '',\n `V${y + h - br}`,\n br ? `Q${x + w},${y + h} ${x + w - br},${y + h}` : '',\n `H${x + bl}`,\n bl ? `Q${x},${y + h} ${x},${y + h - bl}` : '',\n `V${y + tl}`,\n tl ? `Q${x},${y} ${x + tl},${y}` : '',\n 'Z',\n ]\n .filter(Boolean)\n .join('');\n}\n\nfunction defaultStackColor(i: number): string {\n return `var(--prism-color-${(i % 8) + 1})`;\n}\n\nexport function createSparkline(\n container: HTMLElement,\n config: SparklineConfig,\n): ChartHandle<number[] | StackSegment[]> {\n const variant = config.variant ?? 'line';\n const color = config.color ?? 'var(--prism-color-1)';\n const curve = config.curve ?? 'linear';\n const strokeWidth = config.strokeWidth ?? 1.5;\n const fillOpacity = config.fillOpacity;\n const showEndPoint = config.showEndPoint ?? true;\n const gradientId = uniqueId('prism-spark-fill');\n const tappers = createTappers<PrismEvent>();\n let data = config.data;\n\n const base = createChartBase(\n container,\n {\n a11y: config.a11y,\n margin: { bottom: 0, left: 0, right: 0, top: 0 },\n },\n () => {\n tappers.emit({ height: base.dimensions.height, type: 'resize', width: base.dimensions.width });\n renderAll();\n },\n );\n\n const { svg } = base;\n\n svg.classList.add('prism-sparkline');\n\n const innerGroup = createSvgElement('g', { class: 'prism-spark-inner' });\n\n svg.appendChild(innerGroup);\n\n let cleanupInteraction: (() => void) | undefined;\n\n /** Line and area plots are inset so dots on the first and last values are not clipped. */\n function plotArea(): { h: number; inset: number; w: number } {\n const { height, width } = base.dimensions;\n const inset = variant === 'line' || variant === 'area' ? PLOT_INSET : 0;\n\n return { h: Math.max(1, height - inset * 2), inset, w: Math.max(1, width - inset * 2) };\n }\n\n function renderAll(): void {\n const { height: h, width: w } = base.dimensions;\n const plot = plotArea();\n\n while (innerGroup.firstChild) innerGroup.removeChild(innerGroup.firstChild);\n\n innerGroup.setAttribute('transform', `translate(${plot.inset},${plot.inset})`);\n\n if (data.length === 0) return;\n\n if (!isStackData(data) && data.some((v) => !Number.isFinite(v))) {\n warn('createSparkline: data contains non-finite values; they are drawn as the minimum.');\n }\n\n if (variant === 'stack' && isStackData(data)) {\n const stackGroup = createSvgElement('g', { class: 'prism-spark-stack' });\n\n innerGroup.appendChild(stackGroup);\n\n const cornerRadius = config.cornerRadius ?? 4;\n const segs = data as StackSegment[];\n const total = segs.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total > 0) {\n const half = (config.padPixels ?? 0) / 2;\n let xAcc = 0;\n\n segs.forEach((seg, i) => {\n const xStart = Math.round(xAcc);\n\n xAcc += (Math.max(0, seg.value) / total) * w;\n\n const xEnd = i === segs.length - 1 ? w : Math.round(xAcc);\n const isFirst = i === 0;\n const isLast = i === segs.length - 1;\n const drawX = xStart + (isFirst ? 0 : half);\n const drawW = Math.max(0, xEnd - xStart - (isFirst ? 0 : half) - (isLast ? 0 : half));\n const d = buildRoundedStackRect(drawX, 0, drawW, h, cornerRadius, isFirst, isLast);\n const path = createSvgElement('path', { class: 'prism-spark-stack-segment' });\n\n setAttributes(path, { d, fill: seg.color ?? defaultStackColor(i) });\n stackGroup.appendChild(path);\n });\n }\n } else if (variant === 'bar') {\n const barsGroup = createSvgElement('g', { class: 'prism-spark-bars' });\n\n innerGroup.appendChild(barsGroup);\n renderSparkBars(barsGroup, data as number[], w, h, color, config.transition, ac.signal);\n } else {\n if (variant === 'area') {\n const defs = createSvgElement('defs');\n const gradient = createSvgElement('linearGradient', { id: gradientId, x1: 0, x2: 0, y1: 0, y2: 1 });\n\n for (const [offset, className] of [\n [0, 'prism-spark-stop-top'],\n [1, 'prism-spark-stop-bottom'],\n ] as const) {\n const stop = createSvgElement('stop', { class: className, offset, 'stop-color': color });\n\n stop.style.stopColor = color;\n gradient.appendChild(stop);\n }\n\n defs.appendChild(gradient);\n innerGroup.appendChild(defs);\n\n const fill = createSvgElement('path', { class: 'prism-spark-fill' });\n const fillD = buildAreaPath(data as number[], plot.w, plot.h, curve);\n\n setAttributes(fill, { d: fillD, fill: `url(#${gradientId})`, stroke: 'none' });\n fill.style.fillOpacity = fillOpacity === undefined ? '' : String(fillOpacity);\n innerGroup.appendChild(fill);\n }\n\n const path = createSvgElement('path', { class: 'prism-spark-line' });\n const pathD = buildPath(data as number[], plot.w, plot.h, curve);\n\n setAttributes(path, { d: pathD, fill: 'none', stroke: color, 'stroke-width': strokeWidth });\n innerGroup.appendChild(path);\n\n const end = buildTopPoints(data as number[], plot.w, plot.h).at(-1);\n\n if (showEndPoint && end) {\n innerGroup.appendChild(\n createSvgElement('circle', { class: 'prism-spark-end', cx: end.x, cy: end.y, fill: color, r: 2.5 }),\n );\n }\n }\n\n if (!isStackData(data)) attachInteraction(data as number[]);\n }\n\n function attachInteraction(data: number[]): void {\n cleanupInteraction?.();\n cleanupInteraction = undefined;\n\n if (!config.onHover && !config.onClick) return;\n\n if (data.length <= 1) return;\n\n const { h, inset, w } = plotArea();\n\n svg.style.cursor = 'crosshair';\n\n const xStep = w / (data.length - 1);\n const points = variant === 'bar' ? [] : buildTopPoints(data, w, h);\n const marker = createSvgElement('circle', { class: 'prism-spark-marker', fill: color, r: 3.5 });\n const indexAt = (clientX: number): number =>\n Math.max(0, Math.min(data.length - 1, Math.round((clientX - svg.getBoundingClientRect().left - inset) / xStep)));\n\n marker.style.display = 'none';\n innerGroup.appendChild(marker);\n\n const handleMove = (e: MouseEvent) => {\n const idx = indexAt(e.clientX);\n const point = points[idx];\n\n if (point) {\n setAttributes(marker, { cx: point.x, cy: point.y });\n marker.style.display = '';\n }\n\n config.onHover?.({ index: idx, originalEvent: e, value: data[idx] });\n };\n\n const handleLeave = () => {\n marker.style.display = 'none';\n config.onHover?.(null);\n };\n\n const handleClick = (e: MouseEvent) => {\n if (!config.onClick) return;\n\n const idx = indexAt(e.clientX);\n\n config.onClick({ index: idx, originalEvent: e, value: data[idx] });\n };\n\n svg.addEventListener('mousemove', handleMove);\n svg.addEventListener('mouseleave', handleLeave);\n svg.addEventListener('click', handleClick);\n\n cleanupInteraction = () => {\n svg.removeEventListener('mousemove', handleMove);\n svg.removeEventListener('mouseleave', handleLeave);\n svg.removeEventListener('click', handleClick);\n };\n }\n\n const ac = new AbortController();\n let isDisposed = false;\n\n try {\n renderAll();\n\n return {\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n\n dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n tappers.emit({ type: 'dispose' });\n tappers.stop();\n ac.abort();\n cleanupInteraction?.();\n base.dispose();\n },\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n el: svg,\n\n tap: tappers.tap,\n\n update(next) {\n if (isDisposed) throw new PrismRenderError('Cannot update a disposed chart.');\n data = next;\n renderAll();\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n ac.abort();\n cleanupInteraction?.();\n base.dispose();\n throw error instanceof PrismRenderError ? error : new PrismRenderError('Failed to render chart.', { cause: error });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sparkline.js","names":[],"sources":["../../../src/charts/sparkline/sparkline.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { createTappers } from '../../_tappers';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport { createChartBase } from '../../core/chart-base';\nimport { uniqueId } from '../../core/ids';\nimport { PrismRenderError } from '../../errors';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ChartHandle, PrismEvent, SparklineConfig, StackSegment } from '../../types';\n\n/** Fits the 3.5px hover marker plus its ring inside the SVG. */\nconst PLOT_INSET = 5;\n\nfunction buildTopPoints(data: number[], width: number, height: number): Point[] {\n if (data.length === 0) return [];\n\n const xStep = width / Math.max(1, data.length - 1);\n const min = Math.min(...data);\n const max = Math.max(...data);\n const yRange = max - min || 1;\n\n return data.map((v, i) => ({\n x: i * xStep,\n y: height - ((v - min) / yRange) * height,\n }));\n}\n\nfunction buildAreaPathFromPoints(top: Point[], height: number, curve: SparklineConfig['curve']): string {\n if (top.length === 0) return '';\n\n const bottom = top.map((p) => ({ x: p.x, y: height }));\n\n return areaPath(top, bottom, curve ?? 'linear');\n}\n\nfunction buildPathFromPoints(points: Point[], curve: SparklineConfig['curve']): string {\n if (points.length === 0) return '';\n\n return curve === 'monotone' ? monotonePath(points) : curve === 'step' ? stepPath(points) : linePath(points);\n}\n\nfunction isStackData(data: number[] | StackSegment[]): data is StackSegment[] {\n return data.length > 0 && data[0] !== null && typeof data[0] === 'object';\n}\n\nfunction buildRoundedStackRect(\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n roundLeft: boolean,\n roundRight: boolean,\n): string {\n const maxR = Math.min(r, w / 2, h / 2);\n const tl = roundLeft ? maxR : 0;\n const bl = roundLeft ? maxR : 0;\n const tr = roundRight ? maxR : 0;\n const br = roundRight ? maxR : 0;\n\n return [\n `M${x + tl},${y}`,\n `H${x + w - tr}`,\n tr ? `Q${x + w},${y} ${x + w},${y + tr}` : '',\n `V${y + h - br}`,\n br ? `Q${x + w},${y + h} ${x + w - br},${y + h}` : '',\n `H${x + bl}`,\n bl ? `Q${x},${y + h} ${x},${y + h - bl}` : '',\n `V${y + tl}`,\n tl ? `Q${x},${y} ${x + tl},${y}` : '',\n 'Z',\n ]\n .filter(Boolean)\n .join('');\n}\n\nfunction defaultStackColor(i: number): string {\n return `var(--prism-color-${(i % 8) + 1})`;\n}\n\nexport function createSparkline(\n container: HTMLElement,\n config: SparklineConfig,\n): ChartHandle<number[] | StackSegment[]> {\n const variant = config.variant ?? 'line';\n const color = config.color ?? 'var(--prism-color-1)';\n const curve = config.curve ?? 'linear';\n const strokeWidth = config.strokeWidth ?? 1.5;\n const fillOpacity = config.fillOpacity;\n const showEndPoint = config.showEndPoint ?? true;\n const gradientId = uniqueId('prism-spark-fill');\n const tappers = createTappers<PrismEvent>();\n const motion = resolveMotion(config.transition);\n const easing = resolveEasing(motion.easing);\n let data = config.data;\n // Values currently on screen (mid-tween included), in data space so a resize\n // never re-animates: every variant interpolates these and repaints.\n let drawnValues: number[] | null = null;\n let activeTween: (() => void) | null = null;\n\n const base = createChartBase(\n container,\n {\n a11y: config.a11y,\n margin: { bottom: 0, left: 0, right: 0, top: 0 },\n },\n () => {\n tappers.emit({ height: base.dimensions.height, type: 'resize', width: base.dimensions.width });\n renderAll();\n },\n );\n\n const { svg } = base;\n\n svg.classList.add('prism-sparkline');\n\n const innerGroup = createSvgElement('g', { class: 'prism-spark-inner' });\n\n svg.appendChild(innerGroup);\n\n let cleanupInteraction: (() => void) | undefined;\n\n /** Line and area plots are inset so dots on the first and last values are not clipped. */\n function plotArea(): { h: number; inset: number; w: number } {\n const { height, width } = base.dimensions;\n const inset = variant === 'line' || variant === 'area' ? PLOT_INSET : 0;\n\n return { h: Math.max(1, height - inset * 2), inset, w: Math.max(1, width - inset * 2) };\n }\n\n /**\n * Tweens the plotted values from what is on screen to `to`, repainting through\n * `paint`. A first render (or a length change, which has no per-index\n * predecessor) grows out of `floorValue`, the scale's minimum. Unchanged values\n * — a resize re-layout, for instance — repaint without animating.\n */\n function animateValues(to: number[], floorValue: number, paint: (values: number[]) => void): void {\n activeTween?.();\n\n const from = drawnValues?.length === to.length ? drawnValues : to.map(() => floorValue);\n const unchanged = from.every((value, i) => value === to[i]);\n\n if (unchanged || motion.duration === 0) {\n drawnValues = to;\n paint(to);\n\n return;\n }\n\n activeTween = startTween({\n count: 1,\n duration: motion.duration,\n easing,\n onFrame: (progress) => {\n const e = progress(0);\n const values = to.map((value, i) => tweenNumber(from[i], value, e));\n\n drawnValues = values;\n paint(values);\n },\n signal: ac.signal,\n });\n // Paint the starting geometry now: the tween only paints on its first frame\n // callback, which would otherwise leave one blank frame after mount.\n drawnValues = from;\n paint(from);\n }\n\n function renderAll(): void {\n const { height: h, width: w } = base.dimensions;\n const plot = plotArea();\n\n while (innerGroup.firstChild) innerGroup.removeChild(innerGroup.firstChild);\n\n innerGroup.setAttribute('transform', `translate(${plot.inset},${plot.inset})`);\n\n if (data.length === 0) {\n drawnValues = null;\n\n return;\n }\n\n if (!isStackData(data) && data.some((v) => !Number.isFinite(v))) {\n warn('createSparkline: data contains non-finite values; they are drawn as the minimum.');\n }\n\n if (variant === 'stack' && isStackData(data)) {\n const stackGroup = createSvgElement('g', { class: 'prism-spark-stack' });\n\n innerGroup.appendChild(stackGroup);\n\n const cornerRadius = config.cornerRadius ?? 4;\n const segs = data as StackSegment[];\n const total = segs.reduce((s, d) => s + Math.max(0, d.value), 0);\n const paths = segs.map((seg, i) => {\n const path = createSvgElement('path', { class: 'prism-spark-stack-segment' });\n\n setAttributes(path, { fill: seg.color ?? defaultStackColor(i) });\n stackGroup.appendChild(path);\n\n return path;\n });\n\n if (total > 0) {\n animateValues(\n segs.map((seg) => Math.max(0, seg.value)),\n 0,\n (values) => {\n const runningTotal = values.reduce((s, v) => s + v, 0) || 1;\n const half = (config.padPixels ?? 0) / 2;\n let xAcc = 0;\n\n values.forEach((value, i) => {\n const xStart = Math.round(xAcc);\n\n xAcc += (value / runningTotal) * w;\n\n const xEnd = i === values.length - 1 ? w : Math.round(xAcc);\n const isFirst = i === 0;\n const isLast = i === values.length - 1;\n const drawX = xStart + (isFirst ? 0 : half);\n const drawW = Math.max(0, xEnd - xStart - (isFirst ? 0 : half) - (isLast ? 0 : half));\n\n paths[i]?.setAttribute('d', buildRoundedStackRect(drawX, 0, drawW, h, cornerRadius, isFirst, isLast));\n });\n },\n );\n } else {\n // Nothing to draw: clear the recorded geometry so a later update cannot\n // interpolate from values that are no longer on screen.\n activeTween?.();\n drawnValues = null;\n }\n } else if (variant === 'bar') {\n const barsGroup = createSvgElement('g', { class: 'prism-spark-bars' });\n\n innerGroup.appendChild(barsGroup);\n\n const values = data as number[];\n const barMin = Math.min(0, ...values);\n const barRange = Math.max(...values) - barMin || 1;\n const barW = Math.max(1, w / values.length - 1);\n const gap = w / values.length;\n const rects = values.map(() => {\n const rect = createSvgElement('rect', { class: 'prism-spark-bar', fill: color });\n\n barsGroup.appendChild(rect);\n\n return rect;\n });\n\n animateValues(values, barMin, (frame) => {\n for (const [i, rect] of rects.entries()) {\n const barHeight = Math.max(1, ((frame[i] - barMin) / barRange) * h);\n\n setAttributes(rect, { height: barHeight, width: barW, x: i * gap, y: h - barHeight });\n }\n });\n } else {\n const values = data as number[];\n // The scale is fixed to the target values, so a tween moves points along\n // stable axes instead of wobbling as the domain follows each frame.\n const lineMin = Math.min(...values);\n const lineRange = Math.max(...values) - lineMin || 1;\n const xStep = plot.w / Math.max(1, values.length - 1);\n const pointsFromValues = (frame: number[]): Point[] =>\n frame.map((v, i) => ({ x: i * xStep, y: plot.h - ((v - lineMin) / lineRange) * plot.h }));\n\n let fill: SVGPathElement | null = null;\n\n if (variant === 'area') {\n const defs = createSvgElement('defs');\n const gradient = createSvgElement('linearGradient', { id: gradientId, x1: 0, x2: 0, y1: 0, y2: 1 });\n\n for (const [offset, className] of [\n [0, 'prism-spark-stop-top'],\n [1, 'prism-spark-stop-bottom'],\n ] as const) {\n const stop = createSvgElement('stop', { class: className, offset, 'stop-color': color });\n\n stop.style.stopColor = color;\n gradient.appendChild(stop);\n }\n\n defs.appendChild(gradient);\n innerGroup.appendChild(defs);\n\n fill = createSvgElement('path', { class: 'prism-spark-fill' });\n\n setAttributes(fill, { fill: `url(#${gradientId})`, stroke: 'none' });\n fill.style.fillOpacity = fillOpacity === undefined ? '' : String(fillOpacity);\n innerGroup.appendChild(fill);\n }\n\n const path = createSvgElement('path', { class: 'prism-spark-line' });\n\n setAttributes(path, { fill: 'none', stroke: color, 'stroke-width': strokeWidth });\n innerGroup.appendChild(path);\n\n const endDot =\n showEndPoint && values.length > 0\n ? createSvgElement('circle', { class: 'prism-spark-end', fill: color, r: 2.5 })\n : null;\n\n if (endDot) innerGroup.appendChild(endDot);\n\n animateValues(values, lineMin, (frame) => {\n const top = pointsFromValues(frame);\n\n setAttributes(path, { d: buildPathFromPoints(top, curve) });\n\n if (fill) setAttributes(fill, { d: buildAreaPathFromPoints(top, plot.h, curve) });\n\n const end = top.at(-1);\n\n if (endDot && end) setAttributes(endDot, { cx: end.x, cy: end.y });\n });\n }\n\n if (!isStackData(data)) attachInteraction(data as number[]);\n }\n\n function attachInteraction(data: number[]): void {\n cleanupInteraction?.();\n cleanupInteraction = undefined;\n\n if (!config.onHover && !config.onClick) return;\n\n if (data.length <= 1) return;\n\n const { h, inset, w } = plotArea();\n\n svg.style.cursor = 'crosshair';\n\n const xStep = w / (data.length - 1);\n const points = variant === 'bar' ? [] : buildTopPoints(data, w, h);\n const marker = createSvgElement('circle', { class: 'prism-spark-marker', fill: color, r: 3.5 });\n const indexAt = (clientX: number): number =>\n Math.max(0, Math.min(data.length - 1, Math.round((clientX - svg.getBoundingClientRect().left - inset) / xStep)));\n\n marker.style.display = 'none';\n innerGroup.appendChild(marker);\n\n const handleMove = (e: MouseEvent) => {\n const idx = indexAt(e.clientX);\n const point = points[idx];\n\n if (point) {\n setAttributes(marker, { cx: point.x, cy: point.y });\n marker.style.display = '';\n }\n\n config.onHover?.({ index: idx, originalEvent: e, value: data[idx] });\n };\n\n const handleLeave = () => {\n marker.style.display = 'none';\n config.onHover?.(null);\n };\n\n const handleClick = (e: MouseEvent) => {\n if (!config.onClick) return;\n\n const idx = indexAt(e.clientX);\n\n config.onClick({ index: idx, originalEvent: e, value: data[idx] });\n };\n\n svg.addEventListener('mousemove', handleMove);\n svg.addEventListener('mouseleave', handleLeave);\n svg.addEventListener('click', handleClick);\n\n cleanupInteraction = () => {\n svg.removeEventListener('mousemove', handleMove);\n svg.removeEventListener('mouseleave', handleLeave);\n svg.removeEventListener('click', handleClick);\n };\n }\n\n const ac = new AbortController();\n let isDisposed = false;\n\n try {\n renderAll();\n\n return {\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n\n dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n tappers.emit({ type: 'dispose' });\n tappers.stop();\n ac.abort();\n cleanupInteraction?.();\n base.dispose();\n },\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n el: svg,\n\n tap: tappers.tap,\n\n update(next) {\n if (isDisposed) throw new PrismRenderError('Cannot update a disposed chart.');\n data = next;\n renderAll();\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n ac.abort();\n cleanupInteraction?.();\n base.dispose();\n throw error instanceof PrismRenderError ? error : new PrismRenderError('Failed to render chart.', { cause: error });\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- function observeResize(e,t){let n=null,r=new ResizeObserver(e=>{n!==null&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{n=null;let r=e[0];if(r){let{height:e,width:n}=r.contentRect;t(n,e)}})});return r.observe(e),()=>{n!==null&&cancelAnimationFrame(n),r.disconnect()}}exports.observeResize=observeResize;
1
+ function observeResize(e,t){if(typeof ResizeObserver>`u`)return()=>{};let n=null,r=new ResizeObserver(e=>{n!==null&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{n=null;let r=e[0];if(r){let{height:e,width:n}=r.contentRect;t(n,e)}})});return r.observe(e),()=>{n!==null&&cancelAnimationFrame(n),r.disconnect()}}exports.observeResize=observeResize;
2
2
  //# sourceMappingURL=responsive.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"responsive.cjs","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":"AAAA,SAAgB,cAAc,EAAiB,EAA+D,CAC5G,IAAI,EAAuB,KAErB,EAAW,IAAI,eAAgB,GAAY,CAC3C,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAQ,0BAA4B,CAClC,EAAQ,KAER,IAAM,EAAQ,EAAQ,GAEtB,GAAI,EAAO,CACT,GAAM,CAAE,SAAQ,SAAU,EAAM,YAEhC,EAAS,EAAO,CAAM,CACxB,CACF,CAAC,CACH,CAAC,EAID,OAFA,EAAS,QAAQ,CAAE,MAEN,CACP,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAS,WAAW,CACtB,CACF"}
1
+ {"version":3,"file":"responsive.cjs","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n // Environments without ResizeObserver (jsdom, SSR) get a no-op subscription: the chart\n // keeps its initial getBoundingClientRect size and never observes, instead of throwing.\n if (typeof ResizeObserver === 'undefined') return () => {};\n\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":"AAAA,SAAgB,cAAc,EAAiB,EAA+D,CAG5G,GAAI,OAAO,eAAmB,IAAa,UAAa,CAAC,EAEzD,IAAI,EAAuB,KAErB,EAAW,IAAI,eAAgB,GAAY,CAC3C,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAQ,0BAA4B,CAClC,EAAQ,KAER,IAAM,EAAQ,EAAQ,GAEtB,GAAI,EAAO,CACT,GAAM,CAAE,SAAQ,SAAU,EAAM,YAEhC,EAAS,EAAO,CAAM,CACxB,CACF,CAAC,CACH,CAAC,EAID,OAFA,EAAS,QAAQ,CAAE,MAEN,CACP,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAS,WAAW,CACtB,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"responsive.d.ts","sourceRoot":"","sources":["../../src/core/responsive.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA0B5G"}
1
+ {"version":3,"file":"responsive.d.ts","sourceRoot":"","sources":["../../src/core/responsive.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA8B5G"}
@@ -1,2 +1,2 @@
1
- function observeResize(e,t){let n=null,r=new ResizeObserver(e=>{n!==null&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{n=null;let r=e[0];if(r){let{height:e,width:n}=r.contentRect;t(n,e)}})});return r.observe(e),()=>{n!==null&&cancelAnimationFrame(n),r.disconnect()}}export{observeResize};
1
+ function observeResize(e,t){if(typeof ResizeObserver>`u`)return()=>{};let n=null,r=new ResizeObserver(e=>{n!==null&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{n=null;let r=e[0];if(r){let{height:e,width:n}=r.contentRect;t(n,e)}})});return r.observe(e),()=>{n!==null&&cancelAnimationFrame(n),r.disconnect()}}export{observeResize};
2
2
  //# sourceMappingURL=responsive.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"responsive.js","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":"AAAA,SAAgB,cAAc,EAAiB,EAA+D,CAC5G,IAAI,EAAuB,KAErB,EAAW,IAAI,eAAgB,GAAY,CAC3C,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAQ,0BAA4B,CAClC,EAAQ,KAER,IAAM,EAAQ,EAAQ,GAEtB,GAAI,EAAO,CACT,GAAM,CAAE,SAAQ,SAAU,EAAM,YAEhC,EAAS,EAAO,CAAM,CACxB,CACF,CAAC,CACH,CAAC,EAID,OAFA,EAAS,QAAQ,CAAE,MAEN,CACP,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAS,WAAW,CACtB,CACF"}
1
+ {"version":3,"file":"responsive.js","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n // Environments without ResizeObserver (jsdom, SSR) get a no-op subscription: the chart\n // keeps its initial getBoundingClientRect size and never observes, instead of throwing.\n if (typeof ResizeObserver === 'undefined') return () => {};\n\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":"AAAA,SAAgB,cAAc,EAAiB,EAA+D,CAG5G,GAAI,OAAO,eAAmB,IAAa,UAAa,CAAC,EAEzD,IAAI,EAAuB,KAErB,EAAW,IAAI,eAAgB,GAAY,CAC3C,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAQ,0BAA4B,CAClC,EAAQ,KAER,IAAM,EAAQ,EAAQ,GAEtB,GAAI,EAAO,CACT,GAAM,CAAE,SAAQ,SAAU,EAAM,YAEhC,EAAS,EAAO,CAAM,CACxB,CACF,CAAC,CACH,CAAC,EAID,OAFA,EAAS,QAAQ,CAAE,MAEN,CACP,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAS,WAAW,CACtB,CACF"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { EasingFn } from './animation/easing';
1
+ export type { EasingFn, EasingName } from './animation/easing';
2
2
  export { createAreaChart } from './charts/area';
3
3
  export { createBarChart } from './charts/bar';
4
4
  export { createLineChart } from './charts/line';
@@ -11,5 +11,5 @@ export { linearScale } from './scales/linear';
11
11
  export { timeScale } from './scales/time';
12
12
  export type { BandScaleConfig, LinearScaleConfig, TimeScaleConfig } from './scales/types';
13
13
  export { resetTheme, seriesColor, setTheme } from './theme';
14
- export type { AreaChartConfig, AreaSeriesConfig, AxisConfig, AxisPosition, BandScale, BarChartConfig, BarSeriesConfig, BarVariant, BaseChartConfig, ChartA11y, ChartDimensions, ChartEvent, ChartHandle, ChartMargin, ContinuousDatum, CrosshairConfig, Datum, GridConfig, HorizontalAxisPosition, LegendConfig, LegendPosition, LineChartConfig, LineSeriesConfig, PieChartConfig, PieEvent, PieSliceConfig, PieVariant, PrismEvent, PrismTheme, RadarAxisConfig, RadarAxisValue, RadarChartConfig, RadarEvent, RadarGridConfig, RadarSeriesConfig, Scale, Series, SeriesValue, SparklineConfig, SparklineEvent, SparklineVariant, StackSegment, TooltipConfig, TransitionConfig, VerticalAxisPosition, XAxisConfig, YAxisConfig, } from './types';
14
+ export type { AreaChartConfig, AreaSeriesConfig, AxisConfig, AxisPosition, BandScale, BarChartConfig, BarSeriesConfig, BarVariant, BaseChartConfig, ChartA11y, ChartDimensions, ChartEvent, ChartHandle, ChartMargin, ContinuousDatum, CrosshairConfig, Datum, GridConfig, HorizontalAxisPosition, LegendConfig, LegendPosition, LineChartConfig, LineSeriesConfig, PieChartConfig, PieEvent, PieSliceConfig, PieVariant, PrismEvent, PrismTheme, RadarAxisConfig, RadarAxisValue, RadarChartConfig, RadarEvent, RadarGridConfig, RadarSeriesConfig, Scale, Series, SeriesValue, SparklineConfig, SparklineEvent, SparklineVariant, StackSegment, ThemeScope, TooltipConfig, TransitionConfig, TransitionOption, VerticalAxisPosition, XAxisConfig, YAxisConfig, } from './types';
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE1F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,SAAS,EACT,eAAe,EACf,UAAU,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,WAAW,GACZ,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE1F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,SAAS,EACT,eAAe,EACf,UAAU,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,WAAW,GACZ,MAAM,SAAS,CAAC"}
@@ -1,2 +1,2 @@
1
- const e=require("../svg/element.cjs");function createCrosshair(t,n){let r=n===!0||n?.vertical!==!1,i=n!==!0&&n?.horizontal===!0,a=n===!0||n?.snap!==!1,o=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-crosshair`,style:`display:none`}),s=r?e.createSvgElement(`line`,{class:`prism-crosshair-v`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null,c=i?e.createSvgElement(`line`,{class:`prism-crosshair-h`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null;return s&&o.appendChild(s),c&&o.appendChild(c),t.appendChild(o),{hide(){o.style.display=`none`},show(t,n,r,i){o.style.display=``,s&&e.setAttributes(s,{x1:t,x2:t,y1:0,y2:i}),c&&e.setAttributes(c,{x1:0,x2:r,y1:n,y2:n})},snap:a}}exports.createCrosshair=createCrosshair;
1
+ const e=require("../svg/element.cjs");function createCrosshair(t,n){let r=n===!0||n?.vertical!==!1,i=n!==!0&&n?.horizontal===!0,a=n===!0||n?.snap!==!1,o=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-crosshair`,style:`display:none`}),s=r?e.createSvgElement(`line`,{class:`prism-crosshair-v`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null,c=i?e.createSvgElement(`line`,{class:`prism-crosshair-h`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null;return s&&o.appendChild(s),c&&o.appendChild(c),t.appendChild(o),{hide(){o.style.display=`none`},show(t,n,r,i){o.style.display=``,s&&(e.setAttributes(s,{x1:0,x2:0,y1:0,y2:i}),s.style.transform=`translateX(${t}px)`),c&&(e.setAttributes(c,{x1:0,x2:r,y1:0,y2:0}),c.style.transform=`translateY(${n}px)`)},snap:a}}exports.createCrosshair=createCrosshair;
2
2
  //# sourceMappingURL=crosshair.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"crosshair.cjs","names":[],"sources":["../../src/interaction/crosshair.ts"],"sourcesContent":["import { createSvgElement, setAttributes } from '../svg/element';\nimport type { CrosshairConfig } from '../types';\n\nexport interface CrosshairState {\n hide(): void;\n show(x: number, y: number, width: number, height: number): void;\n /** When `false`, the crosshair follows the raw mouse position instead of snapping to the nearest datum. */\n readonly snap: boolean;\n}\n\nexport function createCrosshair(parent: SVGGElement, config?: CrosshairConfig | true): CrosshairState {\n const showVertical = config === true || config?.vertical !== false;\n const showHorizontal = config !== true && config?.horizontal === true;\n const snap = config === true || config?.snap !== false;\n\n const group = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-crosshair', style: 'display:none' });\n\n const vLine = showVertical\n ? createSvgElement('line', { class: 'prism-crosshair-v', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n const hLine = showHorizontal\n ? createSvgElement('line', { class: 'prism-crosshair-h', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n\n if (vLine) group.appendChild(vLine);\n\n if (hLine) group.appendChild(hLine);\n\n parent.appendChild(group);\n\n return {\n hide() {\n group.style.display = 'none';\n },\n show(x: number, y: number, width: number, height: number) {\n group.style.display = '';\n\n if (vLine) setAttributes(vLine, { x1: x, x2: x, y1: 0, y2: height });\n\n if (hLine) setAttributes(hLine, { x1: 0, x2: width, y1: y, y2: y });\n },\n snap,\n };\n}\n"],"mappings":"sCAUA,SAAgB,gBAAgB,EAAqB,EAAiD,CACpG,IAAM,EAAe,IAAW,IAAQ,GAAQ,WAAa,GACvD,EAAiB,IAAW,IAAQ,GAAQ,aAAe,GAC3D,EAAO,IAAW,IAAQ,GAAQ,OAAS,GAE3C,EAAQ,EAAA,iBAAiB,IAAK,CAAE,cAAe,OAAQ,MAAO,kBAAmB,MAAO,cAAe,CAAC,EAExG,EAAQ,EACV,EAAA,iBAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KACE,EAAQ,EACV,EAAA,iBAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KAQJ,OANI,GAAO,EAAM,YAAY,CAAK,EAE9B,GAAO,EAAM,YAAY,CAAK,EAElC,EAAO,YAAY,CAAK,EAEjB,CACL,MAAO,CACL,EAAM,MAAM,QAAU,MACxB,EACA,KAAK,EAAW,EAAW,EAAe,EAAgB,CACxD,EAAM,MAAM,QAAU,GAElB,GAAO,EAAA,cAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,CAAO,CAAC,EAE/D,GAAO,EAAA,cAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAO,GAAI,EAAG,GAAI,CAAE,CAAC,CACpE,EACA,MACF,CACF"}
1
+ {"version":3,"file":"crosshair.cjs","names":[],"sources":["../../src/interaction/crosshair.ts"],"sourcesContent":["import { createSvgElement, setAttributes } from '../svg/element';\nimport type { CrosshairConfig } from '../types';\n\nexport interface CrosshairState {\n hide(): void;\n show(x: number, y: number, width: number, height: number): void;\n /** When `false`, the crosshair follows the raw mouse position instead of snapping to the nearest datum. */\n readonly snap: boolean;\n}\n\n/**\n * Guide lines for the hovered position. Each line is drawn at the origin and placed\n * with a `transform`, so the CSS transition on `transform` glides a snapped guide to\n * the next datum. (`x1`/`y1` are not animatable CSS geometry properties, so the\n * position has to live in the transform.) Because the group starts `display: none`,\n * the first show places the guide instantly instead of sliding it in from the origin.\n */\nexport function createCrosshair(parent: SVGGElement, config?: CrosshairConfig | true): CrosshairState {\n const showVertical = config === true || config?.vertical !== false;\n const showHorizontal = config !== true && config?.horizontal === true;\n const snap = config === true || config?.snap !== false;\n\n const group = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-crosshair', style: 'display:none' });\n\n const vLine = showVertical\n ? createSvgElement('line', { class: 'prism-crosshair-v', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n const hLine = showHorizontal\n ? createSvgElement('line', { class: 'prism-crosshair-h', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n\n if (vLine) group.appendChild(vLine);\n\n if (hLine) group.appendChild(hLine);\n\n parent.appendChild(group);\n\n return {\n hide() {\n group.style.display = 'none';\n },\n show(x: number, y: number, width: number, height: number) {\n group.style.display = '';\n\n if (vLine) {\n setAttributes(vLine, { x1: 0, x2: 0, y1: 0, y2: height });\n vLine.style.transform = `translateX(${x}px)`;\n }\n\n if (hLine) {\n setAttributes(hLine, { x1: 0, x2: width, y1: 0, y2: 0 });\n hLine.style.transform = `translateY(${y}px)`;\n }\n },\n snap,\n };\n}\n"],"mappings":"sCAiBA,SAAgB,gBAAgB,EAAqB,EAAiD,CACpG,IAAM,EAAe,IAAW,IAAQ,GAAQ,WAAa,GACvD,EAAiB,IAAW,IAAQ,GAAQ,aAAe,GAC3D,EAAO,IAAW,IAAQ,GAAQ,OAAS,GAE3C,EAAQ,EAAA,iBAAiB,IAAK,CAAE,cAAe,OAAQ,MAAO,kBAAmB,MAAO,cAAe,CAAC,EAExG,EAAQ,EACV,EAAA,iBAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KACE,EAAQ,EACV,EAAA,iBAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KAQJ,OANI,GAAO,EAAM,YAAY,CAAK,EAE9B,GAAO,EAAM,YAAY,CAAK,EAElC,EAAO,YAAY,CAAK,EAEjB,CACL,MAAO,CACL,EAAM,MAAM,QAAU,MACxB,EACA,KAAK,EAAW,EAAW,EAAe,EAAgB,CACxD,EAAM,MAAM,QAAU,GAElB,IACF,EAAA,cAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,CAAO,CAAC,EACxD,EAAM,MAAM,UAAY,cAAc,EAAE,MAGtC,IACF,EAAA,cAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAO,GAAI,EAAG,GAAI,CAAE,CAAC,EACvD,EAAM,MAAM,UAAY,cAAc,EAAE,KAE5C,EACA,MACF,CACF"}
@@ -5,5 +5,12 @@ export interface CrosshairState {
5
5
  /** When `false`, the crosshair follows the raw mouse position instead of snapping to the nearest datum. */
6
6
  readonly snap: boolean;
7
7
  }
8
+ /**
9
+ * Guide lines for the hovered position. Each line is drawn at the origin and placed
10
+ * with a `transform`, so the CSS transition on `transform` glides a snapped guide to
11
+ * the next datum. (`x1`/`y1` are not animatable CSS geometry properties, so the
12
+ * position has to live in the transform.) Because the group starts `display: none`,
13
+ * the first show places the guide instantly instead of sliding it in from the origin.
14
+ */
8
15
  export declare function createCrosshair(parent: SVGGElement, config?: CrosshairConfig | true): CrosshairState;
9
16
  //# sourceMappingURL=crosshair.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crosshair.d.ts","sourceRoot":"","sources":["../../src/interaction/crosshair.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChE,2GAA2G;IAC3G,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,GAAG,cAAc,CAiCpG"}
1
+ {"version":3,"file":"crosshair.d.ts","sourceRoot":"","sources":["../../src/interaction/crosshair.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChE,2GAA2G;IAC3G,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,GAAG,cAAc,CAuCpG"}
@@ -1,2 +1,2 @@
1
- import{createSvgElement as e,setAttributes as t}from"../svg/element.js";function createCrosshair(n,r){let i=r===!0||r?.vertical!==!1,a=r!==!0&&r?.horizontal===!0,o=r===!0||r?.snap!==!1,s=e(`g`,{"aria-hidden":`true`,class:`prism-crosshair`,style:`display:none`}),c=i?e(`line`,{class:`prism-crosshair-v`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null,l=a?e(`line`,{class:`prism-crosshair-h`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null;return c&&s.appendChild(c),l&&s.appendChild(l),n.appendChild(s),{hide(){s.style.display=`none`},show(e,n,r,i){s.style.display=``,c&&t(c,{x1:e,x2:e,y1:0,y2:i}),l&&t(l,{x1:0,x2:r,y1:n,y2:n})},snap:o}}export{createCrosshair};
1
+ import{createSvgElement as e,setAttributes as t}from"../svg/element.js";function createCrosshair(n,r){let i=r===!0||r?.vertical!==!1,a=r!==!0&&r?.horizontal===!0,o=r===!0||r?.snap!==!1,s=e(`g`,{"aria-hidden":`true`,class:`prism-crosshair`,style:`display:none`}),c=i?e(`line`,{class:`prism-crosshair-v`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null,l=a?e(`line`,{class:`prism-crosshair-h`,"stroke-dasharray":`var(--prism-crosshair-dash, 4 2)`}):null;return c&&s.appendChild(c),l&&s.appendChild(l),n.appendChild(s),{hide(){s.style.display=`none`},show(e,n,r,i){s.style.display=``,c&&(t(c,{x1:0,x2:0,y1:0,y2:i}),c.style.transform=`translateX(${e}px)`),l&&(t(l,{x1:0,x2:r,y1:0,y2:0}),l.style.transform=`translateY(${n}px)`)},snap:o}}export{createCrosshair};
2
2
  //# sourceMappingURL=crosshair.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crosshair.js","names":[],"sources":["../../src/interaction/crosshair.ts"],"sourcesContent":["import { createSvgElement, setAttributes } from '../svg/element';\nimport type { CrosshairConfig } from '../types';\n\nexport interface CrosshairState {\n hide(): void;\n show(x: number, y: number, width: number, height: number): void;\n /** When `false`, the crosshair follows the raw mouse position instead of snapping to the nearest datum. */\n readonly snap: boolean;\n}\n\nexport function createCrosshair(parent: SVGGElement, config?: CrosshairConfig | true): CrosshairState {\n const showVertical = config === true || config?.vertical !== false;\n const showHorizontal = config !== true && config?.horizontal === true;\n const snap = config === true || config?.snap !== false;\n\n const group = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-crosshair', style: 'display:none' });\n\n const vLine = showVertical\n ? createSvgElement('line', { class: 'prism-crosshair-v', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n const hLine = showHorizontal\n ? createSvgElement('line', { class: 'prism-crosshair-h', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n\n if (vLine) group.appendChild(vLine);\n\n if (hLine) group.appendChild(hLine);\n\n parent.appendChild(group);\n\n return {\n hide() {\n group.style.display = 'none';\n },\n show(x: number, y: number, width: number, height: number) {\n group.style.display = '';\n\n if (vLine) setAttributes(vLine, { x1: x, x2: x, y1: 0, y2: height });\n\n if (hLine) setAttributes(hLine, { x1: 0, x2: width, y1: y, y2: y });\n },\n snap,\n };\n}\n"],"mappings":"wEAUA,SAAgB,gBAAgB,EAAqB,EAAiD,CACpG,IAAM,EAAe,IAAW,IAAQ,GAAQ,WAAa,GACvD,EAAiB,IAAW,IAAQ,GAAQ,aAAe,GAC3D,EAAO,IAAW,IAAQ,GAAQ,OAAS,GAE3C,EAAQ,EAAiB,IAAK,CAAE,cAAe,OAAQ,MAAO,kBAAmB,MAAO,cAAe,CAAC,EAExG,EAAQ,EACV,EAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KACE,EAAQ,EACV,EAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KAQJ,OANI,GAAO,EAAM,YAAY,CAAK,EAE9B,GAAO,EAAM,YAAY,CAAK,EAElC,EAAO,YAAY,CAAK,EAEjB,CACL,MAAO,CACL,EAAM,MAAM,QAAU,MACxB,EACA,KAAK,EAAW,EAAW,EAAe,EAAgB,CACxD,EAAM,MAAM,QAAU,GAElB,GAAO,EAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,CAAO,CAAC,EAE/D,GAAO,EAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAO,GAAI,EAAG,GAAI,CAAE,CAAC,CACpE,EACA,MACF,CACF"}
1
+ {"version":3,"file":"crosshair.js","names":[],"sources":["../../src/interaction/crosshair.ts"],"sourcesContent":["import { createSvgElement, setAttributes } from '../svg/element';\nimport type { CrosshairConfig } from '../types';\n\nexport interface CrosshairState {\n hide(): void;\n show(x: number, y: number, width: number, height: number): void;\n /** When `false`, the crosshair follows the raw mouse position instead of snapping to the nearest datum. */\n readonly snap: boolean;\n}\n\n/**\n * Guide lines for the hovered position. Each line is drawn at the origin and placed\n * with a `transform`, so the CSS transition on `transform` glides a snapped guide to\n * the next datum. (`x1`/`y1` are not animatable CSS geometry properties, so the\n * position has to live in the transform.) Because the group starts `display: none`,\n * the first show places the guide instantly instead of sliding it in from the origin.\n */\nexport function createCrosshair(parent: SVGGElement, config?: CrosshairConfig | true): CrosshairState {\n const showVertical = config === true || config?.vertical !== false;\n const showHorizontal = config !== true && config?.horizontal === true;\n const snap = config === true || config?.snap !== false;\n\n const group = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-crosshair', style: 'display:none' });\n\n const vLine = showVertical\n ? createSvgElement('line', { class: 'prism-crosshair-v', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n const hLine = showHorizontal\n ? createSvgElement('line', { class: 'prism-crosshair-h', 'stroke-dasharray': 'var(--prism-crosshair-dash, 4 2)' })\n : null;\n\n if (vLine) group.appendChild(vLine);\n\n if (hLine) group.appendChild(hLine);\n\n parent.appendChild(group);\n\n return {\n hide() {\n group.style.display = 'none';\n },\n show(x: number, y: number, width: number, height: number) {\n group.style.display = '';\n\n if (vLine) {\n setAttributes(vLine, { x1: 0, x2: 0, y1: 0, y2: height });\n vLine.style.transform = `translateX(${x}px)`;\n }\n\n if (hLine) {\n setAttributes(hLine, { x1: 0, x2: width, y1: 0, y2: 0 });\n hLine.style.transform = `translateY(${y}px)`;\n }\n },\n snap,\n };\n}\n"],"mappings":"wEAiBA,SAAgB,gBAAgB,EAAqB,EAAiD,CACpG,IAAM,EAAe,IAAW,IAAQ,GAAQ,WAAa,GACvD,EAAiB,IAAW,IAAQ,GAAQ,aAAe,GAC3D,EAAO,IAAW,IAAQ,GAAQ,OAAS,GAE3C,EAAQ,EAAiB,IAAK,CAAE,cAAe,OAAQ,MAAO,kBAAmB,MAAO,cAAe,CAAC,EAExG,EAAQ,EACV,EAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KACE,EAAQ,EACV,EAAiB,OAAQ,CAAE,MAAO,oBAAqB,mBAAoB,kCAAmC,CAAC,EAC/G,KAQJ,OANI,GAAO,EAAM,YAAY,CAAK,EAE9B,GAAO,EAAM,YAAY,CAAK,EAElC,EAAO,YAAY,CAAK,EAEjB,CACL,MAAO,CACL,EAAM,MAAM,QAAU,MACxB,EACA,KAAK,EAAW,EAAW,EAAe,EAAgB,CACxD,EAAM,MAAM,QAAU,GAElB,IACF,EAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,CAAO,CAAC,EACxD,EAAM,MAAM,UAAY,cAAc,EAAE,MAGtC,IACF,EAAc,EAAO,CAAE,GAAI,EAAG,GAAI,EAAO,GAAI,EAAG,GAAI,CAAE,CAAC,EACvD,EAAM,MAAM,UAAY,cAAc,EAAE,KAE5C,EACA,MACF,CACF"}
@@ -1,2 +1,2 @@
1
- let e=require("@vielzeug/orbit");var t=`position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap`;function comparisonContent(e,n,r,i){let a=e.createElement(`div`),o=e.createElement(`span`),s=e.createElement(`div`),c=e.createElement(`div`);a.className=`prism-tooltip-body`,o.className=`prism-tooltip-sr`,o.style.cssText=t,o.textContent=i,s.setAttribute(`aria-hidden`,`true`),c.className=`prism-tooltip-title`,c.textContent=n,s.appendChild(c);for(let t of r){let n=e.createElement(`div`),r=e.createElement(`span`),i=e.createElement(`span`),a=e.createElement(`span`);n.className=`prism-tooltip-row`,r.className=`prism-tooltip-swatch`,r.style.setProperty(`--prism-swatch`,t.color),i.className=`prism-tooltip-name`,i.textContent=t.name,a.className=`prism-tooltip-value`,a.textContent=t.value,n.append(r,i,a),s.appendChild(n)}return a.append(o,s),a}function createTooltip(t,n){let r=t.style.position,i=getComputedStyle(t).position===`static`;i&&(t.style.position=`relative`);let a=t.ownerDocument.createElement(`div`);a.className=`prism-tooltip`,a.style.position=`absolute`,a.style.pointerEvents=`none`,a.style.top=`0`,a.style.left=`0`,a.setAttribute(`role`,`status`),a.setAttribute(`aria-live`,`polite`),t.appendChild(a);let o=n!==!0&&n?.offset||8,s=n===!0?void 0:n?.render,c=null,l=null,u=!1,cancelClear=()=>{l!==null&&(clearTimeout(l),l=null)},cancelReveal=()=>{c!==null&&(cancelAnimationFrame(c),c=null)},disposeHandle=()=>{cancelReveal(),cancelClear(),a.remove(),i&&t.style.position===`relative`&&(t.style.position=r)};return{dispose:disposeHandle,el:a,hide(){cancelReveal(),cancelClear(),u=!1,a.style.opacity=`0`,l=setTimeout(()=>{l=null,u||(a.textContent=``)},150)},show(n,r,i,l,d){if(!t.isConnected)return;cancelClear();let f=s?s(i,l):d??`${l.name}: ${i.value}`;typeof f==`string`?a.textContent=f:a.replaceChildren(f);let{x:p,y:m}=(0,e.computePosition)({getBoundingClientRect:()=>{let e=t.getBoundingClientRect();return{bottom:e.top+r,height:0,left:e.left+n,right:e.left+n,top:e.top+r,width:0,x:e.left+n,y:e.top+r}}},a,{containingBlock:t,middleware:[(0,e.offset)(o),(0,e.flip)(),(0,e.shift)({padding:8})],placement:`top`});if(a.style.left=`${p}px`,a.style.top=`${m}px`,u){c===null&&(a.style.opacity=`1`);return}u=!0,a.style.opacity=`0`,c=requestAnimationFrame(()=>{c=null,u&&(a.style.opacity=`1`)})},[Symbol.dispose]:disposeHandle}}exports.comparisonContent=comparisonContent,exports.createTooltip=createTooltip;
1
+ let e=require("@vielzeug/orbit");var t=`position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap`;function comparisonContent(e,n,r,i){let a=e.createElement(`div`),o=e.createElement(`span`),s=e.createElement(`div`),c=e.createElement(`div`);a.className=`prism-tooltip-body`,o.className=`prism-tooltip-sr`,o.style.cssText=t,o.textContent=i,s.setAttribute(`aria-hidden`,`true`),c.className=`prism-tooltip-title`,c.textContent=n,s.appendChild(c);for(let t of r){let n=e.createElement(`div`),r=e.createElement(`span`),i=e.createElement(`span`),a=e.createElement(`span`);n.className=`prism-tooltip-row`,r.className=`prism-tooltip-swatch`,r.style.setProperty(`--prism-swatch`,t.color),i.className=`prism-tooltip-name`,i.textContent=t.name,a.className=`prism-tooltip-value`,a.textContent=t.value,n.append(r,i,a),s.appendChild(n)}return a.append(o,s),a}function createTooltip(t,n){let r=t.style.position,i=getComputedStyle(t).position===`static`;i&&(t.style.position=`relative`);let a=t.ownerDocument.createElement(`div`);a.className=`prism-tooltip`,a.style.position=`absolute`,a.style.pointerEvents=`none`,a.style.top=`0`,a.style.left=`0`,a.setAttribute(`role`,`status`),a.setAttribute(`aria-live`,`polite`),t.appendChild(a);let o=n!==!0&&n?.offset||8,s=n===!0?void 0:n?.render,setVisible=e=>{a.classList.toggle(`prism-tooltip--visible`,e),a.style.opacity=e?`1`:`0`},c=null,l=null,u=!1,cancelClear=()=>{l!==null&&(clearTimeout(l),l=null)},cancelReveal=()=>{c!==null&&(cancelAnimationFrame(c),c=null)},disposeHandle=()=>{cancelReveal(),cancelClear(),a.remove(),i&&t.style.position===`relative`&&(t.style.position=r)};return{dispose:disposeHandle,el:a,hide(){cancelReveal(),cancelClear(),u=!1,setVisible(!1),l=setTimeout(()=>{l=null,u||(a.textContent=``)},150)},show(n,r,i,l,d){if(!t.isConnected)return;cancelClear();let f=s?s(i,l):d??`${l.name}: ${i.value}`;typeof f==`string`?a.textContent=f:a.replaceChildren(f);let{x:p,y:m}=(0,e.computePosition)({getBoundingClientRect:()=>{let e=t.getBoundingClientRect();return{bottom:e.top+r,height:0,left:e.left+n,right:e.left+n,top:e.top+r,width:0,x:e.left+n,y:e.top+r}}},a,{containingBlock:t,middleware:[(0,e.offset)(o),(0,e.flip)(),(0,e.shift)({padding:8})],placement:`top`});if(a.style.left=`${p}px`,a.style.top=`${m}px`,u){c===null&&setVisible(!0);return}u=!0,setVisible(!1),c=requestAnimationFrame(()=>{c=null,u&&setVisible(!0)})},[Symbol.dispose]:disposeHandle}}exports.comparisonContent=comparisonContent,exports.createTooltip=createTooltip;
2
2
  //# sourceMappingURL=tooltip.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.cjs","names":[],"sources":["../../src/interaction/tooltip.ts"],"sourcesContent":["import { computePosition, flip, offset, shift } from '@vielzeug/orbit';\nimport type { Datum, Series, TooltipConfig } from '../types';\n\nexport interface TooltipRow {\n color: string;\n name: string;\n value: string;\n}\n\n/** Inline so the spoken text stays hidden even without prism's stylesheet. */\nconst SCREEN_READER_ONLY =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap';\n\n/**\n * Title plus one swatch row per series; text only, so data is never parsed as HTML.\n * `spoken` is what the tooltip's live region announces; the visual rows are aria-hidden.\n */\nexport function comparisonContent(\n doc: Document,\n title: string,\n rows: readonly TooltipRow[],\n spoken: string,\n): HTMLElement {\n const body = doc.createElement('div');\n const sr = doc.createElement('span');\n const visual = doc.createElement('div');\n const head = doc.createElement('div');\n\n body.className = 'prism-tooltip-body';\n sr.className = 'prism-tooltip-sr';\n sr.style.cssText = SCREEN_READER_ONLY;\n sr.textContent = spoken;\n visual.setAttribute('aria-hidden', 'true');\n head.className = 'prism-tooltip-title';\n head.textContent = title;\n visual.appendChild(head);\n\n for (const row of rows) {\n const line = doc.createElement('div');\n const swatch = doc.createElement('span');\n const name = doc.createElement('span');\n const value = doc.createElement('span');\n\n line.className = 'prism-tooltip-row';\n swatch.className = 'prism-tooltip-swatch';\n swatch.style.setProperty('--prism-swatch', row.color);\n name.className = 'prism-tooltip-name';\n name.textContent = row.name;\n value.className = 'prism-tooltip-value';\n value.textContent = row.value;\n line.append(swatch, name, value);\n visual.appendChild(line);\n }\n\n body.append(sr, visual);\n\n return body;\n}\n\nexport interface TooltipState {\n dispose(): void;\n el: HTMLDivElement | null;\n hide(): void;\n /** `content` replaces the default `series: value` body when no custom `render` is configured. */\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string): void;\n [Symbol.dispose](): void;\n}\n\nexport function createTooltip(container: HTMLElement, config?: TooltipConfig | true): TooltipState {\n const previousPosition = container.style.position;\n const changedPosition = getComputedStyle(container).position === 'static';\n\n if (changedPosition) container.style.position = 'relative';\n\n const el = container.ownerDocument.createElement('div');\n\n el.className = 'prism-tooltip';\n el.style.position = 'absolute';\n el.style.pointerEvents = 'none';\n el.style.top = '0';\n el.style.left = '0';\n // Non-modal status text: announced by assistive tech whenever content/hide state changes.\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n container.appendChild(el);\n\n const tooltipOffset: number = (config !== true && config?.offset) || 8;\n const render = config !== true ? config?.render : undefined;\n\n let revealFrame: number | null = null;\n let clearTimer: ReturnType<typeof setTimeout> | null = null;\n let visible = false;\n\n const cancelClear = (): void => {\n if (clearTimer === null) return;\n\n clearTimeout(clearTimer);\n clearTimer = null;\n };\n\n const cancelReveal = (): void => {\n if (revealFrame === null) return;\n\n cancelAnimationFrame(revealFrame);\n revealFrame = null;\n };\n\n const disposeHandle = (): void => {\n cancelReveal();\n cancelClear();\n el.remove();\n if (changedPosition && container.style.position === 'relative') container.style.position = previousPosition;\n };\n\n return {\n dispose: disposeHandle,\n el,\n hide() {\n cancelReveal();\n cancelClear();\n visible = false;\n el.style.opacity = '0';\n clearTimer = setTimeout(() => {\n clearTimer = null;\n\n if (!visible) el.textContent = '';\n }, 150);\n },\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string) {\n if (!container.isConnected) return;\n\n cancelClear();\n\n const body = render ? render(datum, series) : (content ?? `${series.name}: ${datum.value}`);\n\n if (typeof body === 'string') el.textContent = body;\n else el.replaceChildren(body);\n\n const virtualRef = {\n getBoundingClientRect: () => {\n const rect = container.getBoundingClientRect();\n\n return {\n bottom: rect.top + y,\n height: 0,\n left: rect.left + x,\n right: rect.left + x,\n top: rect.top + y,\n width: 0,\n x: rect.left + x,\n y: rect.top + y,\n };\n },\n };\n\n const { x: positionX, y: positionY } = computePosition(virtualRef, el, {\n containingBlock: container,\n middleware: [offset(tooltipOffset), flip(), shift({ padding: 8 })],\n placement: 'top',\n });\n\n el.style.left = `${positionX}px`;\n el.style.top = `${positionY}px`;\n\n if (visible) {\n if (revealFrame === null) el.style.opacity = '1';\n\n return;\n }\n\n visible = true;\n el.style.opacity = '0';\n revealFrame = requestAnimationFrame(() => {\n revealFrame = null;\n\n if (visible) el.style.opacity = '1';\n });\n },\n [Symbol.dispose]: disposeHandle,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tooltip.cjs","names":[],"sources":["../../src/interaction/tooltip.ts"],"sourcesContent":["import { computePosition, flip, offset, shift } from '@vielzeug/orbit';\nimport type { Datum, Series, TooltipConfig } from '../types';\n\nexport interface TooltipRow {\n color: string;\n name: string;\n value: string;\n}\n\n/** Inline so the spoken text stays hidden even without prism's stylesheet. */\nconst SCREEN_READER_ONLY =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap';\n\n/**\n * Title plus one swatch row per series; text only, so data is never parsed as HTML.\n * `spoken` is what the tooltip's live region announces; the visual rows are aria-hidden.\n */\nexport function comparisonContent(\n doc: Document,\n title: string,\n rows: readonly TooltipRow[],\n spoken: string,\n): HTMLElement {\n const body = doc.createElement('div');\n const sr = doc.createElement('span');\n const visual = doc.createElement('div');\n const head = doc.createElement('div');\n\n body.className = 'prism-tooltip-body';\n sr.className = 'prism-tooltip-sr';\n sr.style.cssText = SCREEN_READER_ONLY;\n sr.textContent = spoken;\n visual.setAttribute('aria-hidden', 'true');\n head.className = 'prism-tooltip-title';\n head.textContent = title;\n visual.appendChild(head);\n\n for (const row of rows) {\n const line = doc.createElement('div');\n const swatch = doc.createElement('span');\n const name = doc.createElement('span');\n const value = doc.createElement('span');\n\n line.className = 'prism-tooltip-row';\n swatch.className = 'prism-tooltip-swatch';\n swatch.style.setProperty('--prism-swatch', row.color);\n name.className = 'prism-tooltip-name';\n name.textContent = row.name;\n value.className = 'prism-tooltip-value';\n value.textContent = row.value;\n line.append(swatch, name, value);\n visual.appendChild(line);\n }\n\n body.append(sr, visual);\n\n return body;\n}\n\nexport interface TooltipState {\n dispose(): void;\n el: HTMLDivElement | null;\n hide(): void;\n /** `content` replaces the default `series: value` body when no custom `render` is configured. */\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string): void;\n [Symbol.dispose](): void;\n}\n\nexport function createTooltip(container: HTMLElement, config?: TooltipConfig | true): TooltipState {\n const previousPosition = container.style.position;\n const changedPosition = getComputedStyle(container).position === 'static';\n\n if (changedPosition) container.style.position = 'relative';\n\n const el = container.ownerDocument.createElement('div');\n\n el.className = 'prism-tooltip';\n el.style.position = 'absolute';\n el.style.pointerEvents = 'none';\n el.style.top = '0';\n el.style.left = '0';\n // Non-modal status text: announced by assistive tech whenever content/hide state changes.\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n container.appendChild(el);\n\n const tooltipOffset: number = (config !== true && config?.offset) || 8;\n const render = config !== true ? config?.render : undefined;\n\n // Opacity stays inline (the transition is declared in CSS against the token\n // duration); the class carries the rise, which needs to combine with the\n // left/top positioning without fighting it.\n const setVisible = (next: boolean): void => {\n el.classList.toggle('prism-tooltip--visible', next);\n el.style.opacity = next ? '1' : '0';\n };\n\n let revealFrame: number | null = null;\n let clearTimer: ReturnType<typeof setTimeout> | null = null;\n let visible = false;\n\n const cancelClear = (): void => {\n if (clearTimer === null) return;\n\n clearTimeout(clearTimer);\n clearTimer = null;\n };\n\n const cancelReveal = (): void => {\n if (revealFrame === null) return;\n\n cancelAnimationFrame(revealFrame);\n revealFrame = null;\n };\n\n const disposeHandle = (): void => {\n cancelReveal();\n cancelClear();\n el.remove();\n if (changedPosition && container.style.position === 'relative') container.style.position = previousPosition;\n };\n\n return {\n dispose: disposeHandle,\n el,\n hide() {\n cancelReveal();\n cancelClear();\n visible = false;\n setVisible(false);\n clearTimer = setTimeout(() => {\n clearTimer = null;\n\n if (!visible) el.textContent = '';\n }, 150);\n },\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string) {\n if (!container.isConnected) return;\n\n cancelClear();\n\n const body = render ? render(datum, series) : (content ?? `${series.name}: ${datum.value}`);\n\n if (typeof body === 'string') el.textContent = body;\n else el.replaceChildren(body);\n\n const virtualRef = {\n getBoundingClientRect: () => {\n const rect = container.getBoundingClientRect();\n\n return {\n bottom: rect.top + y,\n height: 0,\n left: rect.left + x,\n right: rect.left + x,\n top: rect.top + y,\n width: 0,\n x: rect.left + x,\n y: rect.top + y,\n };\n },\n };\n\n const { x: positionX, y: positionY } = computePosition(virtualRef, el, {\n containingBlock: container,\n middleware: [offset(tooltipOffset), flip(), shift({ padding: 8 })],\n placement: 'top',\n });\n\n el.style.left = `${positionX}px`;\n el.style.top = `${positionY}px`;\n\n if (visible) {\n if (revealFrame === null) setVisible(true);\n\n return;\n }\n\n visible = true;\n setVisible(false);\n // One frame at the hidden state first: without it the browser has no\n // starting value to transition from and the tooltip would just appear.\n revealFrame = requestAnimationFrame(() => {\n revealFrame = null;\n\n if (visible) setVisible(true);\n });\n },\n [Symbol.dispose]: disposeHandle,\n };\n}\n"],"mappings":"iCAUA,IAAM,EACJ,iGAMF,SAAgB,kBACd,EACA,EACA,EACA,EACa,CACb,IAAM,EAAO,EAAI,cAAc,KAAK,EAC9B,EAAK,EAAI,cAAc,MAAM,EAC7B,EAAS,EAAI,cAAc,KAAK,EAChC,EAAO,EAAI,cAAc,KAAK,EAEpC,EAAK,UAAY,qBACjB,EAAG,UAAY,mBACf,EAAG,MAAM,QAAU,EACnB,EAAG,YAAc,EACjB,EAAO,aAAa,cAAe,MAAM,EACzC,EAAK,UAAY,sBACjB,EAAK,YAAc,EACnB,EAAO,YAAY,CAAI,EAEvB,IAAK,IAAM,KAAO,EAAM,CACtB,IAAM,EAAO,EAAI,cAAc,KAAK,EAC9B,EAAS,EAAI,cAAc,MAAM,EACjC,EAAO,EAAI,cAAc,MAAM,EAC/B,EAAQ,EAAI,cAAc,MAAM,EAEtC,EAAK,UAAY,oBACjB,EAAO,UAAY,uBACnB,EAAO,MAAM,YAAY,iBAAkB,EAAI,KAAK,EACpD,EAAK,UAAY,qBACjB,EAAK,YAAc,EAAI,KACvB,EAAM,UAAY,sBAClB,EAAM,YAAc,EAAI,MACxB,EAAK,OAAO,EAAQ,EAAM,CAAK,EAC/B,EAAO,YAAY,CAAI,CACzB,CAIA,OAFA,EAAK,OAAO,EAAI,CAAM,EAEf,CACT,CAWA,SAAgB,cAAc,EAAwB,EAA6C,CACjG,IAAM,EAAmB,EAAU,MAAM,SACnC,EAAkB,iBAAiB,CAAS,CAAC,CAAC,WAAa,SAE7D,IAAiB,EAAU,MAAM,SAAW,YAEhD,IAAM,EAAK,EAAU,cAAc,cAAc,KAAK,EAEtD,EAAG,UAAY,gBACf,EAAG,MAAM,SAAW,WACpB,EAAG,MAAM,cAAgB,OACzB,EAAG,MAAM,IAAM,IACf,EAAG,MAAM,KAAO,IAEhB,EAAG,aAAa,OAAQ,QAAQ,EAChC,EAAG,aAAa,YAAa,QAAQ,EACrC,EAAU,YAAY,CAAE,EAExB,IAAM,EAAyB,IAAW,IAAQ,GAAQ,QAAW,EAC/D,EAAS,IAAW,GAAwB,IAAA,GAAjB,GAAQ,OAKnC,WAAc,GAAwB,CAC1C,EAAG,UAAU,OAAO,yBAA0B,CAAI,EAClD,EAAG,MAAM,QAAU,EAAO,IAAM,GAClC,EAEI,EAA6B,KAC7B,EAAmD,KACnD,EAAU,GAER,gBAA0B,CAC1B,IAAe,OAEnB,aAAa,CAAU,EACvB,EAAa,KACf,EAEM,iBAA2B,CAC3B,IAAgB,OAEpB,qBAAqB,CAAW,EAChC,EAAc,KAChB,EAEM,kBAA4B,CAChC,aAAa,EACb,YAAY,EACZ,EAAG,OAAO,EACN,GAAmB,EAAU,MAAM,WAAa,aAAY,EAAU,MAAM,SAAW,EAC7F,EAEA,MAAO,CACL,QAAS,cACT,KACA,MAAO,CACL,aAAa,EACb,YAAY,EACZ,EAAU,GACV,WAAW,EAAK,EAChB,EAAa,eAAiB,CAC5B,EAAa,KAER,IAAS,EAAG,YAAc,GACjC,EAAG,GAAG,CACR,EACA,KAAK,EAAW,EAAW,EAAc,EAAgB,EAAyB,CAChF,GAAI,CAAC,EAAU,YAAa,OAE5B,YAAY,EAEZ,IAAM,EAAO,EAAS,EAAO,EAAO,CAAM,EAAK,GAAW,GAAG,EAAO,KAAK,IAAI,EAAM,QAE/E,OAAO,GAAS,SAAU,EAAG,YAAc,EAC1C,EAAG,gBAAgB,CAAI,EAmB5B,GAAM,CAAE,EAAG,EAAW,EAAG,IAAA,EAAc,EAAA,gBAAA,CAAgB,CAhBrD,0BAA6B,CAC3B,IAAM,EAAO,EAAU,sBAAsB,EAE7C,MAAO,CACL,OAAQ,EAAK,IAAM,EACnB,OAAQ,EACR,KAAM,EAAK,KAAO,EAClB,MAAO,EAAK,KAAO,EACnB,IAAK,EAAK,IAAM,EAChB,MAAO,EACP,EAAG,EAAK,KAAO,EACf,EAAG,EAAK,IAAM,CAChB,CACF,CAGqD,EAAY,EAAI,CACrE,gBAAiB,EACjB,WAAY,EAAC,EAAA,EAAA,OAAA,CAAO,CAAa,GAAG,EAAA,EAAA,KAAA,CAAK,GAAG,EAAA,EAAA,MAAA,CAAM,CAAE,QAAS,CAAE,CAAC,CAAC,EACjE,UAAW,KACb,CAAC,EAKD,GAHA,EAAG,MAAM,KAAO,GAAG,EAAU,IAC7B,EAAG,MAAM,IAAM,GAAG,EAAU,IAExB,EAAS,CACP,IAAgB,MAAM,WAAW,EAAI,EAEzC,MACF,CAEA,EAAU,GACV,WAAW,EAAK,EAGhB,EAAc,0BAA4B,CACxC,EAAc,KAEV,GAAS,WAAW,EAAI,CAC9B,CAAC,CACH,GACC,OAAO,SAAU,aACpB,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/interaction/tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,MAAM,GACb,WAAW,CAmCb;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC1B,IAAI,IAAI,IAAI,CAAC;IACb,iGAAiG;IACjG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACxF,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,YAAY,CAgHjG"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/interaction/tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,MAAM,GACb,WAAW,CAmCb;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC1B,IAAI,IAAI,IAAI,CAAC;IACb,iGAAiG;IACjG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACxF,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,YAAY,CA0HjG"}
@@ -1,2 +1,2 @@
1
- import{computePosition as e,flip as t,offset as n,shift as r}from"@vielzeug/orbit";var i=`position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap`;function comparisonContent(e,t,n,r){let a=e.createElement(`div`),o=e.createElement(`span`),s=e.createElement(`div`),c=e.createElement(`div`);a.className=`prism-tooltip-body`,o.className=`prism-tooltip-sr`,o.style.cssText=i,o.textContent=r,s.setAttribute(`aria-hidden`,`true`),c.className=`prism-tooltip-title`,c.textContent=t,s.appendChild(c);for(let t of n){let n=e.createElement(`div`),r=e.createElement(`span`),i=e.createElement(`span`),a=e.createElement(`span`);n.className=`prism-tooltip-row`,r.className=`prism-tooltip-swatch`,r.style.setProperty(`--prism-swatch`,t.color),i.className=`prism-tooltip-name`,i.textContent=t.name,a.className=`prism-tooltip-value`,a.textContent=t.value,n.append(r,i,a),s.appendChild(n)}return a.append(o,s),a}function createTooltip(i,a){let o=i.style.position,s=getComputedStyle(i).position===`static`;s&&(i.style.position=`relative`);let c=i.ownerDocument.createElement(`div`);c.className=`prism-tooltip`,c.style.position=`absolute`,c.style.pointerEvents=`none`,c.style.top=`0`,c.style.left=`0`,c.setAttribute(`role`,`status`),c.setAttribute(`aria-live`,`polite`),i.appendChild(c);let l=a!==!0&&a?.offset||8,u=a===!0?void 0:a?.render,d=null,f=null,p=!1,cancelClear=()=>{f!==null&&(clearTimeout(f),f=null)},cancelReveal=()=>{d!==null&&(cancelAnimationFrame(d),d=null)},disposeHandle=()=>{cancelReveal(),cancelClear(),c.remove(),s&&i.style.position===`relative`&&(i.style.position=o)};return{dispose:disposeHandle,el:c,hide(){cancelReveal(),cancelClear(),p=!1,c.style.opacity=`0`,f=setTimeout(()=>{f=null,p||(c.textContent=``)},150)},show(a,o,s,f,m){if(!i.isConnected)return;cancelClear();let h=u?u(s,f):m??`${f.name}: ${s.value}`;typeof h==`string`?c.textContent=h:c.replaceChildren(h);let{x:g,y:_}=e({getBoundingClientRect:()=>{let e=i.getBoundingClientRect();return{bottom:e.top+o,height:0,left:e.left+a,right:e.left+a,top:e.top+o,width:0,x:e.left+a,y:e.top+o}}},c,{containingBlock:i,middleware:[n(l),t(),r({padding:8})],placement:`top`});if(c.style.left=`${g}px`,c.style.top=`${_}px`,p){d===null&&(c.style.opacity=`1`);return}p=!0,c.style.opacity=`0`,d=requestAnimationFrame(()=>{d=null,p&&(c.style.opacity=`1`)})},[Symbol.dispose]:disposeHandle}}export{comparisonContent,createTooltip};
1
+ import{computePosition as e,flip as t,offset as n,shift as r}from"@vielzeug/orbit";var i=`position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap`;function comparisonContent(e,t,n,r){let a=e.createElement(`div`),o=e.createElement(`span`),s=e.createElement(`div`),c=e.createElement(`div`);a.className=`prism-tooltip-body`,o.className=`prism-tooltip-sr`,o.style.cssText=i,o.textContent=r,s.setAttribute(`aria-hidden`,`true`),c.className=`prism-tooltip-title`,c.textContent=t,s.appendChild(c);for(let t of n){let n=e.createElement(`div`),r=e.createElement(`span`),i=e.createElement(`span`),a=e.createElement(`span`);n.className=`prism-tooltip-row`,r.className=`prism-tooltip-swatch`,r.style.setProperty(`--prism-swatch`,t.color),i.className=`prism-tooltip-name`,i.textContent=t.name,a.className=`prism-tooltip-value`,a.textContent=t.value,n.append(r,i,a),s.appendChild(n)}return a.append(o,s),a}function createTooltip(i,a){let o=i.style.position,s=getComputedStyle(i).position===`static`;s&&(i.style.position=`relative`);let c=i.ownerDocument.createElement(`div`);c.className=`prism-tooltip`,c.style.position=`absolute`,c.style.pointerEvents=`none`,c.style.top=`0`,c.style.left=`0`,c.setAttribute(`role`,`status`),c.setAttribute(`aria-live`,`polite`),i.appendChild(c);let l=a!==!0&&a?.offset||8,u=a===!0?void 0:a?.render,setVisible=e=>{c.classList.toggle(`prism-tooltip--visible`,e),c.style.opacity=e?`1`:`0`},d=null,f=null,p=!1,cancelClear=()=>{f!==null&&(clearTimeout(f),f=null)},cancelReveal=()=>{d!==null&&(cancelAnimationFrame(d),d=null)},disposeHandle=()=>{cancelReveal(),cancelClear(),c.remove(),s&&i.style.position===`relative`&&(i.style.position=o)};return{dispose:disposeHandle,el:c,hide(){cancelReveal(),cancelClear(),p=!1,setVisible(!1),f=setTimeout(()=>{f=null,p||(c.textContent=``)},150)},show(a,o,s,f,m){if(!i.isConnected)return;cancelClear();let h=u?u(s,f):m??`${f.name}: ${s.value}`;typeof h==`string`?c.textContent=h:c.replaceChildren(h);let{x:g,y:_}=e({getBoundingClientRect:()=>{let e=i.getBoundingClientRect();return{bottom:e.top+o,height:0,left:e.left+a,right:e.left+a,top:e.top+o,width:0,x:e.left+a,y:e.top+o}}},c,{containingBlock:i,middleware:[n(l),t(),r({padding:8})],placement:`top`});if(c.style.left=`${g}px`,c.style.top=`${_}px`,p){d===null&&setVisible(!0);return}p=!0,setVisible(!1),d=requestAnimationFrame(()=>{d=null,p&&setVisible(!0)})},[Symbol.dispose]:disposeHandle}}export{comparisonContent,createTooltip};
2
2
  //# sourceMappingURL=tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","names":[],"sources":["../../src/interaction/tooltip.ts"],"sourcesContent":["import { computePosition, flip, offset, shift } from '@vielzeug/orbit';\nimport type { Datum, Series, TooltipConfig } from '../types';\n\nexport interface TooltipRow {\n color: string;\n name: string;\n value: string;\n}\n\n/** Inline so the spoken text stays hidden even without prism's stylesheet. */\nconst SCREEN_READER_ONLY =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap';\n\n/**\n * Title plus one swatch row per series; text only, so data is never parsed as HTML.\n * `spoken` is what the tooltip's live region announces; the visual rows are aria-hidden.\n */\nexport function comparisonContent(\n doc: Document,\n title: string,\n rows: readonly TooltipRow[],\n spoken: string,\n): HTMLElement {\n const body = doc.createElement('div');\n const sr = doc.createElement('span');\n const visual = doc.createElement('div');\n const head = doc.createElement('div');\n\n body.className = 'prism-tooltip-body';\n sr.className = 'prism-tooltip-sr';\n sr.style.cssText = SCREEN_READER_ONLY;\n sr.textContent = spoken;\n visual.setAttribute('aria-hidden', 'true');\n head.className = 'prism-tooltip-title';\n head.textContent = title;\n visual.appendChild(head);\n\n for (const row of rows) {\n const line = doc.createElement('div');\n const swatch = doc.createElement('span');\n const name = doc.createElement('span');\n const value = doc.createElement('span');\n\n line.className = 'prism-tooltip-row';\n swatch.className = 'prism-tooltip-swatch';\n swatch.style.setProperty('--prism-swatch', row.color);\n name.className = 'prism-tooltip-name';\n name.textContent = row.name;\n value.className = 'prism-tooltip-value';\n value.textContent = row.value;\n line.append(swatch, name, value);\n visual.appendChild(line);\n }\n\n body.append(sr, visual);\n\n return body;\n}\n\nexport interface TooltipState {\n dispose(): void;\n el: HTMLDivElement | null;\n hide(): void;\n /** `content` replaces the default `series: value` body when no custom `render` is configured. */\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string): void;\n [Symbol.dispose](): void;\n}\n\nexport function createTooltip(container: HTMLElement, config?: TooltipConfig | true): TooltipState {\n const previousPosition = container.style.position;\n const changedPosition = getComputedStyle(container).position === 'static';\n\n if (changedPosition) container.style.position = 'relative';\n\n const el = container.ownerDocument.createElement('div');\n\n el.className = 'prism-tooltip';\n el.style.position = 'absolute';\n el.style.pointerEvents = 'none';\n el.style.top = '0';\n el.style.left = '0';\n // Non-modal status text: announced by assistive tech whenever content/hide state changes.\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n container.appendChild(el);\n\n const tooltipOffset: number = (config !== true && config?.offset) || 8;\n const render = config !== true ? config?.render : undefined;\n\n let revealFrame: number | null = null;\n let clearTimer: ReturnType<typeof setTimeout> | null = null;\n let visible = false;\n\n const cancelClear = (): void => {\n if (clearTimer === null) return;\n\n clearTimeout(clearTimer);\n clearTimer = null;\n };\n\n const cancelReveal = (): void => {\n if (revealFrame === null) return;\n\n cancelAnimationFrame(revealFrame);\n revealFrame = null;\n };\n\n const disposeHandle = (): void => {\n cancelReveal();\n cancelClear();\n el.remove();\n if (changedPosition && container.style.position === 'relative') container.style.position = previousPosition;\n };\n\n return {\n dispose: disposeHandle,\n el,\n hide() {\n cancelReveal();\n cancelClear();\n visible = false;\n el.style.opacity = '0';\n clearTimer = setTimeout(() => {\n clearTimer = null;\n\n if (!visible) el.textContent = '';\n }, 150);\n },\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string) {\n if (!container.isConnected) return;\n\n cancelClear();\n\n const body = render ? render(datum, series) : (content ?? `${series.name}: ${datum.value}`);\n\n if (typeof body === 'string') el.textContent = body;\n else el.replaceChildren(body);\n\n const virtualRef = {\n getBoundingClientRect: () => {\n const rect = container.getBoundingClientRect();\n\n return {\n bottom: rect.top + y,\n height: 0,\n left: rect.left + x,\n right: rect.left + x,\n top: rect.top + y,\n width: 0,\n x: rect.left + x,\n y: rect.top + y,\n };\n },\n };\n\n const { x: positionX, y: positionY } = computePosition(virtualRef, el, {\n containingBlock: container,\n middleware: [offset(tooltipOffset), flip(), shift({ padding: 8 })],\n placement: 'top',\n });\n\n el.style.left = `${positionX}px`;\n el.style.top = `${positionY}px`;\n\n if (visible) {\n if (revealFrame === null) el.style.opacity = '1';\n\n return;\n }\n\n visible = true;\n el.style.opacity = '0';\n revealFrame = requestAnimationFrame(() => {\n revealFrame = null;\n\n if (visible) el.style.opacity = '1';\n });\n },\n [Symbol.dispose]: disposeHandle,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tooltip.js","names":[],"sources":["../../src/interaction/tooltip.ts"],"sourcesContent":["import { computePosition, flip, offset, shift } from '@vielzeug/orbit';\nimport type { Datum, Series, TooltipConfig } from '../types';\n\nexport interface TooltipRow {\n color: string;\n name: string;\n value: string;\n}\n\n/** Inline so the spoken text stays hidden even without prism's stylesheet. */\nconst SCREEN_READER_ONLY =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap';\n\n/**\n * Title plus one swatch row per series; text only, so data is never parsed as HTML.\n * `spoken` is what the tooltip's live region announces; the visual rows are aria-hidden.\n */\nexport function comparisonContent(\n doc: Document,\n title: string,\n rows: readonly TooltipRow[],\n spoken: string,\n): HTMLElement {\n const body = doc.createElement('div');\n const sr = doc.createElement('span');\n const visual = doc.createElement('div');\n const head = doc.createElement('div');\n\n body.className = 'prism-tooltip-body';\n sr.className = 'prism-tooltip-sr';\n sr.style.cssText = SCREEN_READER_ONLY;\n sr.textContent = spoken;\n visual.setAttribute('aria-hidden', 'true');\n head.className = 'prism-tooltip-title';\n head.textContent = title;\n visual.appendChild(head);\n\n for (const row of rows) {\n const line = doc.createElement('div');\n const swatch = doc.createElement('span');\n const name = doc.createElement('span');\n const value = doc.createElement('span');\n\n line.className = 'prism-tooltip-row';\n swatch.className = 'prism-tooltip-swatch';\n swatch.style.setProperty('--prism-swatch', row.color);\n name.className = 'prism-tooltip-name';\n name.textContent = row.name;\n value.className = 'prism-tooltip-value';\n value.textContent = row.value;\n line.append(swatch, name, value);\n visual.appendChild(line);\n }\n\n body.append(sr, visual);\n\n return body;\n}\n\nexport interface TooltipState {\n dispose(): void;\n el: HTMLDivElement | null;\n hide(): void;\n /** `content` replaces the default `series: value` body when no custom `render` is configured. */\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string): void;\n [Symbol.dispose](): void;\n}\n\nexport function createTooltip(container: HTMLElement, config?: TooltipConfig | true): TooltipState {\n const previousPosition = container.style.position;\n const changedPosition = getComputedStyle(container).position === 'static';\n\n if (changedPosition) container.style.position = 'relative';\n\n const el = container.ownerDocument.createElement('div');\n\n el.className = 'prism-tooltip';\n el.style.position = 'absolute';\n el.style.pointerEvents = 'none';\n el.style.top = '0';\n el.style.left = '0';\n // Non-modal status text: announced by assistive tech whenever content/hide state changes.\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n container.appendChild(el);\n\n const tooltipOffset: number = (config !== true && config?.offset) || 8;\n const render = config !== true ? config?.render : undefined;\n\n // Opacity stays inline (the transition is declared in CSS against the token\n // duration); the class carries the rise, which needs to combine with the\n // left/top positioning without fighting it.\n const setVisible = (next: boolean): void => {\n el.classList.toggle('prism-tooltip--visible', next);\n el.style.opacity = next ? '1' : '0';\n };\n\n let revealFrame: number | null = null;\n let clearTimer: ReturnType<typeof setTimeout> | null = null;\n let visible = false;\n\n const cancelClear = (): void => {\n if (clearTimer === null) return;\n\n clearTimeout(clearTimer);\n clearTimer = null;\n };\n\n const cancelReveal = (): void => {\n if (revealFrame === null) return;\n\n cancelAnimationFrame(revealFrame);\n revealFrame = null;\n };\n\n const disposeHandle = (): void => {\n cancelReveal();\n cancelClear();\n el.remove();\n if (changedPosition && container.style.position === 'relative') container.style.position = previousPosition;\n };\n\n return {\n dispose: disposeHandle,\n el,\n hide() {\n cancelReveal();\n cancelClear();\n visible = false;\n setVisible(false);\n clearTimer = setTimeout(() => {\n clearTimer = null;\n\n if (!visible) el.textContent = '';\n }, 150);\n },\n show(x: number, y: number, datum: Datum, series: Series, content?: Node | string) {\n if (!container.isConnected) return;\n\n cancelClear();\n\n const body = render ? render(datum, series) : (content ?? `${series.name}: ${datum.value}`);\n\n if (typeof body === 'string') el.textContent = body;\n else el.replaceChildren(body);\n\n const virtualRef = {\n getBoundingClientRect: () => {\n const rect = container.getBoundingClientRect();\n\n return {\n bottom: rect.top + y,\n height: 0,\n left: rect.left + x,\n right: rect.left + x,\n top: rect.top + y,\n width: 0,\n x: rect.left + x,\n y: rect.top + y,\n };\n },\n };\n\n const { x: positionX, y: positionY } = computePosition(virtualRef, el, {\n containingBlock: container,\n middleware: [offset(tooltipOffset), flip(), shift({ padding: 8 })],\n placement: 'top',\n });\n\n el.style.left = `${positionX}px`;\n el.style.top = `${positionY}px`;\n\n if (visible) {\n if (revealFrame === null) setVisible(true);\n\n return;\n }\n\n visible = true;\n setVisible(false);\n // One frame at the hidden state first: without it the browser has no\n // starting value to transition from and the tooltip would just appear.\n revealFrame = requestAnimationFrame(() => {\n revealFrame = null;\n\n if (visible) setVisible(true);\n });\n },\n [Symbol.dispose]: disposeHandle,\n };\n}\n"],"mappings":"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"}