tiptap-markdown-react 0.17.0 → 0.17.1

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.
@@ -0,0 +1 @@
1
+ export {};
package/dist/reader.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-CBvptTaQ.js";
3
- import { R as R2, a as a2, e, b as b2 } from "./ReportContent-CwcppHl8.js";
2
+ import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-BTQWajGD.js";
3
+ import { R as R2, a as a2, e, b as b2 } from "./ReportContent-MgbebxPV.js";
4
4
  export {
5
5
  C as ChartMount,
6
6
  a as CitationInteractive,
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from "react/jsx-runtime";
3
3
  import { useRef, useEffect } from "react";
4
- import { R as ReportContent, p as parseChartFenceBody } from "./ReportContent-CwcppHl8.js";
4
+ import { R as ReportContent, p as parseChartFenceBody } from "./ReportContent-MgbebxPV.js";
5
5
  import { Chart, CategoryScale, LinearScale, PointElement, LineElement, BarElement, ArcElement, LineController, BarController, PieController, DoughnutController, Filler, Legend, Tooltip } from "chart.js";
6
6
  function toNumber(value) {
7
7
  if (typeof value === "number" && !Number.isNaN(value)) return value;
@@ -493,4 +493,4 @@ export {
493
493
  readCitationAttrs as r,
494
494
  scrollToTocHeading as s
495
495
  };
496
- //# sourceMappingURL=scrollToTocHeading-CBvptTaQ.js.map
496
+ //# sourceMappingURL=scrollToTocHeading-BTQWajGD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scrollToTocHeading-CBvptTaQ.js","sources":["../src/chart/mapData.ts","../src/chart/theme.ts","../src/chart/renderChart.ts","../src/citationDom.ts","../src/components/CitationInteractive.tsx","../src/components/ReportContentInteractive.tsx","../src/components/ChartMount.tsx","../src/components/ReportContentWithCharts.tsx","../src/toc/scrollToTocHeading.ts"],"sourcesContent":["import type { ChartConfig, ChartPayload } from './types';\n\nexport interface ChartJsPoint {\n x: string | number;\n y: number;\n category?: string;\n type?: string;\n}\n\nfunction toNumber(value: unknown): number {\n if (typeof value === 'number' && !Number.isNaN(value)) return value;\n if (typeof value === 'string') {\n const n = Number(value.replace(/,/g, ''));\n if (!Number.isNaN(n)) return n;\n }\n return 0;\n}\n\n/**\n * Map table rows to flat chart points for one config.\n * colorLegend → series `type`; groupBy stored as category (no UI filter in v1).\n */\nexport function mapChartDataItems(\n config: ChartConfig,\n dataSource: Record<string, unknown>[],\n): ChartJsPoint[] {\n const xKey = config.x!;\n const yKey = config.y!;\n const legendKey = config.colorLegend;\n const groupKey = config.groupBy;\n\n let rows = [...dataSource];\n const sortKey = config.sortBy;\n if (sortKey) {\n rows.sort((a, b) => {\n const av = a[sortKey];\n const bv = b[sortKey];\n if (typeof av === 'number' && typeof bv === 'number') return av - bv;\n return String(av ?? '').localeCompare(String(bv ?? ''), undefined, {\n numeric: true,\n });\n });\n }\n\n return rows.map((row) => {\n const point: ChartJsPoint = {\n x: row[xKey] as string | number,\n y: toNumber(row[yKey]),\n };\n if (legendKey) point.type = String(row[legendKey] ?? '');\n if (groupKey) point.category = String(row[groupKey] ?? '');\n return point;\n });\n}\n\nexport interface BuiltChartData {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n }[];\n isCartesian: boolean;\n}\n\n/** Build Chart.js labels/datasets for one active config. */\nexport function buildChartJsData(\n config: ChartConfig,\n payload: Pick<ChartPayload, 'dataSource'>,\n): BuiltChartData {\n const points = mapChartDataItems(config, payload.dataSource);\n const type = config.chartType;\n const isCartesian = !['pie', 'donut'].includes(type);\n\n if (!isCartesian) {\n return {\n labels: points.map((p) => String(p.x)),\n datasets: [\n {\n label: config.title || config.y || 'value',\n data: points.map((p) => p.y),\n },\n ],\n isCartesian: false,\n };\n }\n\n const seriesKeys = new Set<string>();\n for (const p of points) {\n seriesKeys.add(p.type || config.title || config.y || 'series');\n }\n const seriesList = [...seriesKeys];\n const labelSet: string[] = [];\n for (const p of points) {\n const lab = String(p.x);\n if (!labelSet.includes(lab)) labelSet.push(lab);\n }\n\n const datasets = seriesList.map((series) => ({\n label: series,\n data: labelSet.map((lab) => {\n const hit = points.find(\n (p) =>\n String(p.x) === lab &&\n (p.type || config.title || config.y || 'series') === series,\n );\n return hit ? hit.y : 0;\n }),\n }));\n\n return { labels: labelSet, datasets, isCartesian: true };\n}\n","import type { ChartTheme } from './types';\n\nconst DEFAULT_PALETTE = [\n '#3b82f6',\n '#10b981',\n '#f59e0b',\n '#ef4444',\n '#8b5cf6',\n '#06b6d4',\n '#ec4899',\n '#84cc16',\n];\n\nfunction readCssVar(\n el: HTMLElement | null,\n name: string,\n fallback: string,\n): string {\n if (!el || typeof getComputedStyle === 'undefined') return fallback;\n const v = getComputedStyle(el).getPropertyValue(name).trim();\n return v || fallback;\n}\n\n/** Resolve theme from --tmr-* CSS variables + optional host override. */\nexport function resolveChartTheme(\n host: HTMLElement | null,\n override?: ChartTheme | null,\n): Required<\n Pick<\n ChartTheme,\n | 'backgroundColor'\n | 'textColor'\n | 'gridColor'\n | 'borderColor'\n | 'fontFamily'\n | 'palette'\n >\n> {\n const base = {\n backgroundColor: readCssVar(host, '--tmr-bg', '#ffffff'),\n textColor: readCssVar(host, '--tmr-fg', '#1f2937'),\n gridColor: readCssVar(host, '--tmr-border', '#e5e7eb'),\n borderColor: readCssVar(host, '--tmr-border', '#e5e7eb'),\n fontFamily: readCssVar(\n host,\n '--tmr-font',\n 'ui-sans-serif, system-ui, sans-serif',\n ),\n palette: DEFAULT_PALETTE,\n };\n if (!override) return base;\n return {\n backgroundColor: override.backgroundColor ?? base.backgroundColor,\n textColor: override.textColor ?? base.textColor,\n gridColor: override.gridColor ?? base.gridColor,\n borderColor: override.borderColor ?? base.borderColor,\n fontFamily: override.fontFamily ?? base.fontFamily,\n palette:\n override.palette && override.palette.length > 0\n ? override.palette\n : base.palette,\n };\n}\n","import {\n ArcElement,\n BarController,\n BarElement,\n CategoryScale,\n Chart,\n DoughnutController,\n Filler,\n Legend,\n LineController,\n LineElement,\n LinearScale,\n PieController,\n PointElement,\n Tooltip,\n type ChartConfiguration,\n type ChartType,\n} from 'chart.js';\nimport { buildChartJsData } from './mapData';\nimport { resolveChartTheme } from './theme';\nimport type { ChartConfig, ChartPayload, ChartTheme } from './types';\n\nlet registered = false;\n\nfunction ensureRegister() {\n if (registered) return;\n if (typeof window === 'undefined') return;\n Chart.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n BarElement,\n ArcElement,\n LineController,\n BarController,\n PieController,\n DoughnutController,\n Filler,\n Legend,\n Tooltip,\n );\n registered = true;\n}\n\nfunction toChartJsType(chartType: string): ChartType {\n switch (chartType) {\n case 'bar':\n return 'bar';\n case 'column':\n return 'bar';\n case 'line':\n return 'line';\n case 'area':\n return 'line';\n case 'pie':\n return 'pie';\n case 'donut':\n return 'doughnut';\n default:\n return 'bar';\n }\n}\n\nexport interface RenderChartOptions {\n canvas: HTMLCanvasElement;\n config: ChartConfig;\n payload: Pick<ChartPayload, 'dataSource' | 'columns'>;\n theme?: ChartTheme | null;\n /** Existing instance to update in place (streaming). */\n chart?: Chart | null;\n}\n\nexport function renderOrUpdateChart({\n canvas,\n config,\n payload,\n theme,\n chart,\n}: RenderChartOptions): Chart | null {\n if (typeof window === 'undefined') return null;\n ensureRegister();\n\n const host = canvas.parentElement;\n const colors = resolveChartTheme(host, theme);\n const built = buildChartJsData(config, payload);\n const jsType = toChartJsType(config.chartType);\n const isBarHorizontal = config.chartType === 'bar';\n const isArea = config.chartType === 'area';\n\n const datasets = built.datasets.map((ds, i) => {\n const color = colors.palette[i % colors.palette.length];\n if (!built.isCartesian) {\n return {\n ...ds,\n backgroundColor: built.labels.map(\n (_, j) => colors.palette[j % colors.palette.length],\n ),\n borderWidth: 0,\n };\n }\n return {\n ...ds,\n backgroundColor: isArea ? `${color}33` : color,\n borderColor: color,\n borderWidth: 2,\n fill: isArea,\n tension: 0.25,\n };\n });\n\n const configuration: ChartConfiguration = {\n type: jsType,\n data: {\n labels: built.labels,\n datasets,\n },\n options: {\n indexAxis: isBarHorizontal ? 'y' : 'x',\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n display: built.datasets.length > 1 || !built.isCartesian,\n labels: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n },\n title: { display: false },\n tooltip: {\n titleFont: { family: colors.fontFamily },\n bodyFont: { family: colors.fontFamily },\n },\n },\n scales: built.isCartesian\n ? {\n x: {\n ticks: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n grid: { color: colors.gridColor },\n border: { color: colors.borderColor },\n },\n y: {\n ticks: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n grid: { color: colors.gridColor },\n border: { color: colors.borderColor },\n },\n }\n : undefined,\n },\n };\n\n if (chart) {\n (chart.config as { type: ChartType }).type = jsType;\n chart.data.labels = configuration.data.labels;\n chart.data.datasets = configuration.data.datasets as never;\n chart.options = configuration.options as never;\n chart.update('none');\n return chart;\n }\n\n return new Chart(canvas, configuration);\n}\n\nexport function destroyChart(chart: Chart | null | undefined) {\n chart?.destroy();\n}\n","/**\n * 从事件目标向上找到 `.citation-ref`(且必须在 root 内)。\n * SSR 阅读页事件委托与单测共用。\n */\nexport function findCitationRefElement(\n target: EventTarget | null,\n root: ParentNode,\n): HTMLElement | null {\n let node: Node | null = null;\n if (target instanceof Element) node = target;\n else if (target instanceof Text) node = target.parentElement;\n else if (target instanceof Node) node = target.parentElement;\n if (!(node instanceof Element)) return null;\n const el = node.closest('.citation-ref');\n if (!(el instanceof HTMLElement)) return null;\n if (!root.contains(el)) return null;\n return el;\n}\n\n/** 从圆标 DOM 读取 attrs(与 CitationRef renderHTML 的 data-* 对齐)。 */\nexport function readCitationAttrs(el: HTMLElement): {\n index: string;\n url: string | null;\n title: string | null;\n} {\n return {\n index: el.getAttribute('data-index') || el.textContent?.trim() || '',\n url: el.getAttribute('data-url'),\n title: el.getAttribute('data-title'),\n };\n}\n","'use client';\n\nimport { useEffect, useRef, type RefObject } from 'react';\nimport {\n findCitationRefElement,\n readCitationAttrs,\n} from '../citationDom';\nimport type {\n OnCitationEnter,\n OnCitationLeave,\n} from '../citationTypes';\n\nexport interface CitationInteractiveProps {\n /**\n * 包含 `ReportContent` HTML 的根节点(其内应有 `.citation-ref`)。\n * 用同一 ref 包住 ReportContent 即可。\n */\n containerRef: RefObject<HTMLElement | null>;\n /** 点击圆标。宿主据此 setState 打开自己的 Popover。 */\n onCitationEnter: OnCitationEnter;\n /**\n * 点正文非圆标处 / 再点同一圆标 / Escape。\n * 库立即回调;浮层开关由宿主管。\n */\n onCitationLeave: OnCitationLeave;\n}\n\n/**\n * SSR 阅读页脚注增强:只做 **click** 事件委托,不持有 open 状态。\n *\n * ```tsx\n * <CitationInteractive\n * containerRef={ref}\n * onCitationEnter={setActive}\n * onCitationLeave={() => setActive(null)}\n * />\n * ```\n */\nexport function CitationInteractive({\n containerRef,\n onCitationEnter,\n onCitationLeave,\n}: CitationInteractiveProps) {\n const enterRef = useRef(onCitationEnter);\n const leaveRef = useRef(onCitationLeave);\n enterRef.current = onCitationEnter;\n leaveRef.current = onCitationLeave;\n\n useEffect(() => {\n const root = containerRef.current;\n if (!root) return;\n\n let currentEl: HTMLElement | null = null;\n\n const emitEnter = (el: HTMLElement) => {\n currentEl = el;\n const attrs = readCitationAttrs(el);\n enterRef.current({ index: attrs.index, attrs, anchorEl: el });\n };\n\n const emitLeave = () => {\n if (!currentEl) return;\n currentEl = null;\n leaveRef.current();\n };\n\n const ACTIVE_ATTR = 'data-tmr-citation-active';\n\n const onClick = (e: MouseEvent) => {\n const el = findCitationRefElement(e.target, root);\n if (el) {\n // 捕获阶段就取消默认,避免圆标内 <a> 跳转\n e.preventDefault();\n e.stopPropagation();\n // 仅当该圆标仍处于打开态时再点才关闭(宿主可能已外部关闭,attr 已清)\n if (el === currentEl && el.hasAttribute(ACTIVE_ATTR)) {\n emitLeave();\n return;\n }\n emitEnter(el);\n return;\n }\n emitLeave();\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') emitLeave();\n };\n\n root.addEventListener('click', onClick, true);\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n root.removeEventListener('click', onClick, true);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [containerRef]);\n\n return null;\n}\n","'use client';\n\nimport { useRef, type ComponentProps } from 'react';\nimport type { OnCitationEnter, OnCitationLeave } from '../citationTypes';\nimport { ReportContent } from '../ReportContent';\nimport { CitationInteractive } from './CitationInteractive';\n\nexport interface ReportContentInteractiveProps\n extends Omit<ComponentProps<typeof ReportContent>, 'ref'> {\n /** 点击圆标:宿主 setState 打开自己的 Popover。 */\n onCitationEnter: OnCitationEnter;\n /** 点外部 / 再点圆标 / Escape:宿主关闭。 */\n onCitationLeave: OnCitationLeave;\n}\n\n/**\n * SSR HTML 阅读 + 脚注 click 委托的便捷封装。\n * 内部:`ReportContent` + `CitationInteractive`(只报事件,仅 click)。\n */\nexport function ReportContentInteractive({\n onCitationEnter,\n onCitationLeave,\n className,\n html,\n ...rest\n}: ReportContentInteractiveProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n return (\n <div ref={ref} className={className}>\n <ReportContent html={html} {...rest} />\n <CitationInteractive\n containerRef={ref}\n onCitationEnter={onCitationEnter}\n onCitationLeave={onCitationLeave}\n />\n </div>\n );\n}\n","'use client';\n\nimport type { Chart as ChartJs } from 'chart.js';\nimport { useEffect, useRef, type RefObject } from 'react';\nimport { parseChartFenceBody } from '../chart/parse';\nimport { destroyChart, renderOrUpdateChart } from '../chart/renderChart';\nimport type { ChartTheme } from '../chart/types';\nimport '../styles/chart.css';\n\nexport interface ChartMountProps {\n containerRef: RefObject<HTMLElement | null>;\n chartTheme?: ChartTheme | null;\n /** Re-scan when this changes (e.g. html string). */\n html?: string;\n}\n\nfunction hydrateOne(\n el: HTMLElement,\n theme: ChartTheme | null | undefined,\n registry: Map<HTMLElement, ChartJs>,\n) {\n const raw = el.getAttribute('data-chart');\n const payload = parseChartFenceBody(raw ?? '');\n if (!payload?.config.length) return;\n\n let host = el.querySelector('.tmr-chart-canvas-host') as HTMLElement | null;\n if (!host) {\n host = document.createElement('div');\n host.className = 'tmr-chart-canvas-host';\n el.appendChild(host);\n }\n host.classList.remove('tmr-chart-skeleton');\n\n let canvas = host.querySelector('canvas');\n if (!canvas) {\n canvas = document.createElement('canvas');\n host.innerHTML = '';\n host.appendChild(canvas);\n }\n\n const config = payload.config[0];\n const height = config.height ?? 320;\n host.style.height = `${height}px`;\n\n if (payload.config.length > 1 && !el.querySelector('.tmr-chart-tabs')) {\n const tabs = document.createElement('div');\n tabs.className = 'tmr-chart-tabs';\n tabs.setAttribute('role', 'tablist');\n payload.config.forEach((c, i) => {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tmr-chart-tab';\n btn.setAttribute('role', 'tab');\n btn.dataset.active = i === 0 ? 'true' : 'false';\n btn.textContent = c.title?.trim() || `${c.chartType} ${i + 1}`;\n btn.addEventListener('click', () => {\n tabs.querySelectorAll('.tmr-chart-tab').forEach((b, j) => {\n (b as HTMLElement).dataset.active = j === i ? 'true' : 'false';\n });\n const existing = registry.get(el);\n destroyChart(existing);\n const next = renderOrUpdateChart({\n canvas: canvas!,\n config: payload.config[i],\n payload,\n theme,\n chart: null,\n });\n if (next) registry.set(el, next);\n const titleEl = el.querySelector('.tmr-chart-title');\n if (titleEl && payload.config[i].title) {\n titleEl.textContent = String(payload.config[i].title);\n titleEl.classList.remove('tmr-chart-title--empty');\n }\n });\n tabs.appendChild(btn);\n });\n el.insertBefore(tabs, host);\n }\n\n const existing = registry.get(el);\n const chart = renderOrUpdateChart({\n canvas,\n config,\n payload,\n theme,\n chart: existing ?? null,\n });\n if (chart) registry.set(el, chart);\n}\n\n/**\n * Hydrate SSR chart placeholders inside a container (reading page).\n */\nexport function ChartMount({\n containerRef,\n chartTheme,\n html,\n}: ChartMountProps) {\n const registryRef = useRef(new Map<HTMLElement, ChartJs>());\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const registry = registryRef.current;\n registry.forEach((chart) => destroyChart(chart));\n registry.clear();\n\n container\n .querySelectorAll<HTMLElement>('div[data-type=\"chart\"]')\n .forEach((el) => hydrateOne(el, chartTheme, registry));\n\n return () => {\n registry.forEach((chart) => destroyChart(chart));\n registry.clear();\n };\n }, [containerRef, chartTheme, html]);\n\n return null;\n}\n\n/** Imperative helper for hosts that prefer not to use the component. */\nexport function mountChartsInContainer(\n container: HTMLElement,\n chartTheme?: ChartTheme | null,\n): () => void {\n const registry = new Map<HTMLElement, ChartJs>();\n container\n .querySelectorAll<HTMLElement>('div[data-type=\"chart\"]')\n .forEach((el) => hydrateOne(el, chartTheme, registry));\n return () => {\n registry.forEach((c) => destroyChart(c));\n registry.clear();\n };\n}\n","'use client';\n\nimport { useRef, type ComponentProps } from 'react';\nimport type { ChartTheme } from '../chart/types';\nimport type { OnCitationEnter, OnCitationLeave } from '../citationTypes';\nimport { ReportContent } from '../ReportContent';\nimport { ChartMount } from './ChartMount';\nimport { CitationInteractive } from './CitationInteractive';\n\nexport interface ReportContentWithChartsProps\n extends Omit<ComponentProps<typeof ReportContent>, 'ref'> {\n onCitationEnter?: OnCitationEnter;\n onCitationLeave?: OnCitationLeave;\n chartTheme?: ChartTheme | null;\n}\n\n/**\n * SSR HTML reading surface with Chart.js hydration (+ optional citation clicks).\n */\nexport function ReportContentWithCharts({\n onCitationEnter,\n onCitationLeave,\n chartTheme,\n className,\n html,\n ...rest\n}: ReportContentWithChartsProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n return (\n <div ref={ref} className={className}>\n <ReportContent html={html} {...rest} />\n <ChartMount\n containerRef={ref}\n chartTheme={chartTheme}\n html={html}\n />\n {onCitationEnter && onCitationLeave ? (\n <CitationInteractive\n containerRef={ref}\n onCitationEnter={onCitationEnter}\n onCitationLeave={onCitationLeave}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * 目录点击 → 平滑滚到对应标题。\n *\n * 不依赖浏览器 `scrollTo({behavior:'smooth'})` / `scrollIntoView({behavior:'smooth'})`——\n * 在 flex + overflow 嵌套布局下(父级 `overflow:hidden`、自身 `flex:1; overflow-y:auto`),\n * Chrome 的 compositor 驱动 smooth scroll 会静默失效。\n *\n * 改用 `requestAnimationFrame` + easeOutCubic 缓动,直接操作 `scrollTop`,\n * 主线程一次性 400ms 动画,点击触发的单次滚动无感知性能差异。\n *\n * 尊重 `prefers-reduced-motion: reduce`——此时瞬间跳转,无动画。\n */\n\n/** 缓动:easeOutCubic。t ∈ [0, 1]。 */\nfunction easeOutCubic(t: number): number {\n return 1 - (1 - t) * (1 - t) * (1 - t);\n}\n\n/**\n * 平滑滚动(或瞬间跳转)到指定 `data-toc-id` 的标题。\n *\n * @param headingId - TOC item 的 id,对应 DOM 上 `data-toc-id` 属性值\n * @param scrollContainer - 滚动容器(如 `.scrollArea`)\n * @param options - `duration`:动画时长 ms,默认 400\n */\nexport function scrollToTocHeading(\n headingId: string,\n scrollContainer: HTMLElement,\n options?: { duration?: number },\n): void {\n const el = scrollContainer.querySelector<HTMLElement>(\n `[data-toc-id=\"${CSS.escape(headingId)}\"]`,\n );\n if (!el) return;\n\n const startTop = scrollContainer.scrollTop;\n const rootRect = scrollContainer.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const targetTop = startTop + (elRect.top - rootRect.top);\n\n // prefers-reduced-motion:瞬间跳转\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n scrollContainer.scrollTop = targetTop;\n return;\n }\n\n // 手动平滑滚动\n const duration = options?.duration ?? 400;\n const start = performance.now();\n const animate = () => {\n const t = Math.min((performance.now() - start) / duration, 1);\n scrollContainer.scrollTop = startTop + (targetTop - startTop) * easeOutCubic(t);\n if (t < 1) requestAnimationFrame(animate);\n };\n requestAnimationFrame(animate);\n}\n"],"names":["existing"],"mappings":"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"}
1
+ {"version":3,"file":"scrollToTocHeading-BTQWajGD.js","sources":["../src/chart/mapData.ts","../src/chart/theme.ts","../src/chart/renderChart.ts","../src/citationDom.ts","../src/components/CitationInteractive.tsx","../src/components/ReportContentInteractive.tsx","../src/components/ChartMount.tsx","../src/components/ReportContentWithCharts.tsx","../src/toc/scrollToTocHeading.ts"],"sourcesContent":["import type { ChartConfig, ChartPayload } from './types';\n\nexport interface ChartJsPoint {\n x: string | number;\n y: number;\n category?: string;\n type?: string;\n}\n\nfunction toNumber(value: unknown): number {\n if (typeof value === 'number' && !Number.isNaN(value)) return value;\n if (typeof value === 'string') {\n const n = Number(value.replace(/,/g, ''));\n if (!Number.isNaN(n)) return n;\n }\n return 0;\n}\n\n/**\n * Map table rows to flat chart points for one config.\n * colorLegend → series `type`; groupBy stored as category (no UI filter in v1).\n */\nexport function mapChartDataItems(\n config: ChartConfig,\n dataSource: Record<string, unknown>[],\n): ChartJsPoint[] {\n const xKey = config.x!;\n const yKey = config.y!;\n const legendKey = config.colorLegend;\n const groupKey = config.groupBy;\n\n let rows = [...dataSource];\n const sortKey = config.sortBy;\n if (sortKey) {\n rows.sort((a, b) => {\n const av = a[sortKey];\n const bv = b[sortKey];\n if (typeof av === 'number' && typeof bv === 'number') return av - bv;\n return String(av ?? '').localeCompare(String(bv ?? ''), undefined, {\n numeric: true,\n });\n });\n }\n\n return rows.map((row) => {\n const point: ChartJsPoint = {\n x: row[xKey] as string | number,\n y: toNumber(row[yKey]),\n };\n if (legendKey) point.type = String(row[legendKey] ?? '');\n if (groupKey) point.category = String(row[groupKey] ?? '');\n return point;\n });\n}\n\nexport interface BuiltChartData {\n labels: string[];\n datasets: {\n label: string;\n data: number[];\n }[];\n isCartesian: boolean;\n}\n\n/** Build Chart.js labels/datasets for one active config. */\nexport function buildChartJsData(\n config: ChartConfig,\n payload: Pick<ChartPayload, 'dataSource'>,\n): BuiltChartData {\n const points = mapChartDataItems(config, payload.dataSource);\n const type = config.chartType;\n const isCartesian = !['pie', 'donut'].includes(type);\n\n if (!isCartesian) {\n return {\n labels: points.map((p) => String(p.x)),\n datasets: [\n {\n label: config.title || config.y || 'value',\n data: points.map((p) => p.y),\n },\n ],\n isCartesian: false,\n };\n }\n\n const seriesKeys = new Set<string>();\n for (const p of points) {\n seriesKeys.add(p.type || config.title || config.y || 'series');\n }\n const seriesList = [...seriesKeys];\n const labelSet: string[] = [];\n for (const p of points) {\n const lab = String(p.x);\n if (!labelSet.includes(lab)) labelSet.push(lab);\n }\n\n const datasets = seriesList.map((series) => ({\n label: series,\n data: labelSet.map((lab) => {\n const hit = points.find(\n (p) =>\n String(p.x) === lab &&\n (p.type || config.title || config.y || 'series') === series,\n );\n return hit ? hit.y : 0;\n }),\n }));\n\n return { labels: labelSet, datasets, isCartesian: true };\n}\n","import type { ChartTheme } from './types';\n\nconst DEFAULT_PALETTE = [\n '#3b82f6',\n '#10b981',\n '#f59e0b',\n '#ef4444',\n '#8b5cf6',\n '#06b6d4',\n '#ec4899',\n '#84cc16',\n];\n\nfunction readCssVar(\n el: HTMLElement | null,\n name: string,\n fallback: string,\n): string {\n if (!el || typeof getComputedStyle === 'undefined') return fallback;\n const v = getComputedStyle(el).getPropertyValue(name).trim();\n return v || fallback;\n}\n\n/** Resolve theme from --tmr-* CSS variables + optional host override. */\nexport function resolveChartTheme(\n host: HTMLElement | null,\n override?: ChartTheme | null,\n): Required<\n Pick<\n ChartTheme,\n | 'backgroundColor'\n | 'textColor'\n | 'gridColor'\n | 'borderColor'\n | 'fontFamily'\n | 'palette'\n >\n> {\n const base = {\n backgroundColor: readCssVar(host, '--tmr-bg', '#ffffff'),\n textColor: readCssVar(host, '--tmr-fg', '#1f2937'),\n gridColor: readCssVar(host, '--tmr-border', '#e5e7eb'),\n borderColor: readCssVar(host, '--tmr-border', '#e5e7eb'),\n fontFamily: readCssVar(\n host,\n '--tmr-font',\n 'ui-sans-serif, system-ui, sans-serif',\n ),\n palette: DEFAULT_PALETTE,\n };\n if (!override) return base;\n return {\n backgroundColor: override.backgroundColor ?? base.backgroundColor,\n textColor: override.textColor ?? base.textColor,\n gridColor: override.gridColor ?? base.gridColor,\n borderColor: override.borderColor ?? base.borderColor,\n fontFamily: override.fontFamily ?? base.fontFamily,\n palette:\n override.palette && override.palette.length > 0\n ? override.palette\n : base.palette,\n };\n}\n","import {\n ArcElement,\n BarController,\n BarElement,\n CategoryScale,\n Chart,\n DoughnutController,\n Filler,\n Legend,\n LineController,\n LineElement,\n LinearScale,\n PieController,\n PointElement,\n Tooltip,\n type ChartConfiguration,\n type ChartType,\n} from 'chart.js';\nimport { buildChartJsData } from './mapData';\nimport { resolveChartTheme } from './theme';\nimport type { ChartConfig, ChartPayload, ChartTheme } from './types';\n\nlet registered = false;\n\nfunction ensureRegister() {\n if (registered) return;\n if (typeof window === 'undefined') return;\n Chart.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n BarElement,\n ArcElement,\n LineController,\n BarController,\n PieController,\n DoughnutController,\n Filler,\n Legend,\n Tooltip,\n );\n registered = true;\n}\n\nfunction toChartJsType(chartType: string): ChartType {\n switch (chartType) {\n case 'bar':\n return 'bar';\n case 'column':\n return 'bar';\n case 'line':\n return 'line';\n case 'area':\n return 'line';\n case 'pie':\n return 'pie';\n case 'donut':\n return 'doughnut';\n default:\n return 'bar';\n }\n}\n\nexport interface RenderChartOptions {\n canvas: HTMLCanvasElement;\n config: ChartConfig;\n payload: Pick<ChartPayload, 'dataSource' | 'columns'>;\n theme?: ChartTheme | null;\n /** Existing instance to update in place (streaming). */\n chart?: Chart | null;\n}\n\nexport function renderOrUpdateChart({\n canvas,\n config,\n payload,\n theme,\n chart,\n}: RenderChartOptions): Chart | null {\n if (typeof window === 'undefined') return null;\n ensureRegister();\n\n const host = canvas.parentElement;\n const colors = resolveChartTheme(host, theme);\n const built = buildChartJsData(config, payload);\n const jsType = toChartJsType(config.chartType);\n const isBarHorizontal = config.chartType === 'bar';\n const isArea = config.chartType === 'area';\n\n const datasets = built.datasets.map((ds, i) => {\n const color = colors.palette[i % colors.palette.length];\n if (!built.isCartesian) {\n return {\n ...ds,\n backgroundColor: built.labels.map(\n (_, j) => colors.palette[j % colors.palette.length],\n ),\n borderWidth: 0,\n };\n }\n return {\n ...ds,\n backgroundColor: isArea ? `${color}33` : color,\n borderColor: color,\n borderWidth: 2,\n fill: isArea,\n tension: 0.25,\n };\n });\n\n const configuration: ChartConfiguration = {\n type: jsType,\n data: {\n labels: built.labels,\n datasets,\n },\n options: {\n indexAxis: isBarHorizontal ? 'y' : 'x',\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n display: built.datasets.length > 1 || !built.isCartesian,\n labels: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n },\n title: { display: false },\n tooltip: {\n titleFont: { family: colors.fontFamily },\n bodyFont: { family: colors.fontFamily },\n },\n },\n scales: built.isCartesian\n ? {\n x: {\n ticks: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n grid: { color: colors.gridColor },\n border: { color: colors.borderColor },\n },\n y: {\n ticks: {\n color: colors.textColor,\n font: { family: colors.fontFamily },\n },\n grid: { color: colors.gridColor },\n border: { color: colors.borderColor },\n },\n }\n : undefined,\n },\n };\n\n if (chart) {\n (chart.config as { type: ChartType }).type = jsType;\n chart.data.labels = configuration.data.labels;\n chart.data.datasets = configuration.data.datasets as never;\n chart.options = configuration.options as never;\n chart.update('none');\n return chart;\n }\n\n return new Chart(canvas, configuration);\n}\n\nexport function destroyChart(chart: Chart | null | undefined) {\n chart?.destroy();\n}\n","/**\n * 从事件目标向上找到 `.citation-ref`(且必须在 root 内)。\n * SSR 阅读页事件委托与单测共用。\n */\nexport function findCitationRefElement(\n target: EventTarget | null,\n root: ParentNode,\n): HTMLElement | null {\n let node: Node | null = null;\n if (target instanceof Element) node = target;\n else if (target instanceof Text) node = target.parentElement;\n else if (target instanceof Node) node = target.parentElement;\n if (!(node instanceof Element)) return null;\n const el = node.closest('.citation-ref');\n if (!(el instanceof HTMLElement)) return null;\n if (!root.contains(el)) return null;\n return el;\n}\n\n/** 从圆标 DOM 读取 attrs(与 CitationRef renderHTML 的 data-* 对齐)。 */\nexport function readCitationAttrs(el: HTMLElement): {\n index: string;\n url: string | null;\n title: string | null;\n} {\n return {\n index: el.getAttribute('data-index') || el.textContent?.trim() || '',\n url: el.getAttribute('data-url'),\n title: el.getAttribute('data-title'),\n };\n}\n","'use client';\n\nimport { useEffect, useRef, type RefObject } from 'react';\nimport {\n findCitationRefElement,\n readCitationAttrs,\n} from '../citationDom';\nimport type {\n OnCitationEnter,\n OnCitationLeave,\n} from '../citationTypes';\n\nexport interface CitationInteractiveProps {\n /**\n * 包含 `ReportContent` HTML 的根节点(其内应有 `.citation-ref`)。\n * 用同一 ref 包住 ReportContent 即可。\n */\n containerRef: RefObject<HTMLElement | null>;\n /** 点击圆标。宿主据此 setState 打开自己的 Popover。 */\n onCitationEnter: OnCitationEnter;\n /**\n * 点正文非圆标处 / 再点同一圆标 / Escape。\n * 库立即回调;浮层开关由宿主管。\n */\n onCitationLeave: OnCitationLeave;\n}\n\n/**\n * SSR 阅读页脚注增强:只做 **click** 事件委托,不持有 open 状态。\n *\n * ```tsx\n * <CitationInteractive\n * containerRef={ref}\n * onCitationEnter={setActive}\n * onCitationLeave={() => setActive(null)}\n * />\n * ```\n */\nexport function CitationInteractive({\n containerRef,\n onCitationEnter,\n onCitationLeave,\n}: CitationInteractiveProps) {\n const enterRef = useRef(onCitationEnter);\n const leaveRef = useRef(onCitationLeave);\n enterRef.current = onCitationEnter;\n leaveRef.current = onCitationLeave;\n\n useEffect(() => {\n const root = containerRef.current;\n if (!root) return;\n\n let currentEl: HTMLElement | null = null;\n\n const emitEnter = (el: HTMLElement) => {\n currentEl = el;\n const attrs = readCitationAttrs(el);\n enterRef.current({ index: attrs.index, attrs, anchorEl: el });\n };\n\n const emitLeave = () => {\n if (!currentEl) return;\n currentEl = null;\n leaveRef.current();\n };\n\n const ACTIVE_ATTR = 'data-tmr-citation-active';\n\n const onClick = (e: MouseEvent) => {\n const el = findCitationRefElement(e.target, root);\n if (el) {\n // 捕获阶段就取消默认,避免圆标内 <a> 跳转\n e.preventDefault();\n e.stopPropagation();\n // 仅当该圆标仍处于打开态时再点才关闭(宿主可能已外部关闭,attr 已清)\n if (el === currentEl && el.hasAttribute(ACTIVE_ATTR)) {\n emitLeave();\n return;\n }\n emitEnter(el);\n return;\n }\n emitLeave();\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') emitLeave();\n };\n\n root.addEventListener('click', onClick, true);\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n root.removeEventListener('click', onClick, true);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [containerRef]);\n\n return null;\n}\n","'use client';\n\nimport { useRef, type ComponentProps } from 'react';\nimport type { OnCitationEnter, OnCitationLeave } from '../citationTypes';\nimport { ReportContent } from '../ReportContent';\nimport { CitationInteractive } from './CitationInteractive';\n\nexport interface ReportContentInteractiveProps\n extends Omit<ComponentProps<typeof ReportContent>, 'ref'> {\n /** 点击圆标:宿主 setState 打开自己的 Popover。 */\n onCitationEnter: OnCitationEnter;\n /** 点外部 / 再点圆标 / Escape:宿主关闭。 */\n onCitationLeave: OnCitationLeave;\n}\n\n/**\n * SSR HTML 阅读 + 脚注 click 委托的便捷封装。\n * 内部:`ReportContent` + `CitationInteractive`(只报事件,仅 click)。\n */\nexport function ReportContentInteractive({\n onCitationEnter,\n onCitationLeave,\n className,\n html,\n ...rest\n}: ReportContentInteractiveProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n return (\n <div ref={ref} className={className}>\n <ReportContent html={html} {...rest} />\n <CitationInteractive\n containerRef={ref}\n onCitationEnter={onCitationEnter}\n onCitationLeave={onCitationLeave}\n />\n </div>\n );\n}\n","'use client';\n\nimport type { Chart as ChartJs } from 'chart.js';\nimport { useEffect, useRef, type RefObject } from 'react';\nimport { parseChartFenceBody } from '../chart/parse';\nimport { destroyChart, renderOrUpdateChart } from '../chart/renderChart';\nimport type { ChartTheme } from '../chart/types';\nimport '../styles/chart.css';\n\nexport interface ChartMountProps {\n containerRef: RefObject<HTMLElement | null>;\n chartTheme?: ChartTheme | null;\n /** Re-scan when this changes (e.g. html string). */\n html?: string;\n}\n\nfunction hydrateOne(\n el: HTMLElement,\n theme: ChartTheme | null | undefined,\n registry: Map<HTMLElement, ChartJs>,\n) {\n const raw = el.getAttribute('data-chart');\n const payload = parseChartFenceBody(raw ?? '');\n if (!payload?.config.length) return;\n\n let host = el.querySelector('.tmr-chart-canvas-host') as HTMLElement | null;\n if (!host) {\n host = document.createElement('div');\n host.className = 'tmr-chart-canvas-host';\n el.appendChild(host);\n }\n host.classList.remove('tmr-chart-skeleton');\n\n let canvas = host.querySelector('canvas');\n if (!canvas) {\n canvas = document.createElement('canvas');\n host.innerHTML = '';\n host.appendChild(canvas);\n }\n\n const config = payload.config[0];\n const height = config.height ?? 320;\n host.style.height = `${height}px`;\n\n if (payload.config.length > 1 && !el.querySelector('.tmr-chart-tabs')) {\n const tabs = document.createElement('div');\n tabs.className = 'tmr-chart-tabs';\n tabs.setAttribute('role', 'tablist');\n payload.config.forEach((c, i) => {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tmr-chart-tab';\n btn.setAttribute('role', 'tab');\n btn.dataset.active = i === 0 ? 'true' : 'false';\n btn.textContent = c.title?.trim() || `${c.chartType} ${i + 1}`;\n btn.addEventListener('click', () => {\n tabs.querySelectorAll('.tmr-chart-tab').forEach((b, j) => {\n (b as HTMLElement).dataset.active = j === i ? 'true' : 'false';\n });\n const existing = registry.get(el);\n destroyChart(existing);\n const next = renderOrUpdateChart({\n canvas: canvas!,\n config: payload.config[i],\n payload,\n theme,\n chart: null,\n });\n if (next) registry.set(el, next);\n const titleEl = el.querySelector('.tmr-chart-title');\n if (titleEl && payload.config[i].title) {\n titleEl.textContent = String(payload.config[i].title);\n titleEl.classList.remove('tmr-chart-title--empty');\n }\n });\n tabs.appendChild(btn);\n });\n el.insertBefore(tabs, host);\n }\n\n const existing = registry.get(el);\n const chart = renderOrUpdateChart({\n canvas,\n config,\n payload,\n theme,\n chart: existing ?? null,\n });\n if (chart) registry.set(el, chart);\n}\n\n/**\n * Hydrate SSR chart placeholders inside a container (reading page).\n */\nexport function ChartMount({\n containerRef,\n chartTheme,\n html,\n}: ChartMountProps) {\n const registryRef = useRef(new Map<HTMLElement, ChartJs>());\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const registry = registryRef.current;\n registry.forEach((chart) => destroyChart(chart));\n registry.clear();\n\n container\n .querySelectorAll<HTMLElement>('div[data-type=\"chart\"]')\n .forEach((el) => hydrateOne(el, chartTheme, registry));\n\n return () => {\n registry.forEach((chart) => destroyChart(chart));\n registry.clear();\n };\n }, [containerRef, chartTheme, html]);\n\n return null;\n}\n\n/** Imperative helper for hosts that prefer not to use the component. */\nexport function mountChartsInContainer(\n container: HTMLElement,\n chartTheme?: ChartTheme | null,\n): () => void {\n const registry = new Map<HTMLElement, ChartJs>();\n container\n .querySelectorAll<HTMLElement>('div[data-type=\"chart\"]')\n .forEach((el) => hydrateOne(el, chartTheme, registry));\n return () => {\n registry.forEach((c) => destroyChart(c));\n registry.clear();\n };\n}\n","'use client';\n\nimport { useRef, type ComponentProps } from 'react';\nimport type { ChartTheme } from '../chart/types';\nimport type { OnCitationEnter, OnCitationLeave } from '../citationTypes';\nimport { ReportContent } from '../ReportContent';\nimport { ChartMount } from './ChartMount';\nimport { CitationInteractive } from './CitationInteractive';\n\nexport interface ReportContentWithChartsProps\n extends Omit<ComponentProps<typeof ReportContent>, 'ref'> {\n onCitationEnter?: OnCitationEnter;\n onCitationLeave?: OnCitationLeave;\n chartTheme?: ChartTheme | null;\n}\n\n/**\n * SSR HTML reading surface with Chart.js hydration (+ optional citation clicks).\n */\nexport function ReportContentWithCharts({\n onCitationEnter,\n onCitationLeave,\n chartTheme,\n className,\n html,\n ...rest\n}: ReportContentWithChartsProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n return (\n <div ref={ref} className={className}>\n <ReportContent html={html} {...rest} />\n <ChartMount\n containerRef={ref}\n chartTheme={chartTheme}\n html={html}\n />\n {onCitationEnter && onCitationLeave ? (\n <CitationInteractive\n containerRef={ref}\n onCitationEnter={onCitationEnter}\n onCitationLeave={onCitationLeave}\n />\n ) : null}\n </div>\n );\n}\n","/**\n * 目录点击 → 平滑滚到对应标题。\n *\n * 不依赖浏览器 `scrollTo({behavior:'smooth'})` / `scrollIntoView({behavior:'smooth'})`——\n * 在 flex + overflow 嵌套布局下(父级 `overflow:hidden`、自身 `flex:1; overflow-y:auto`),\n * Chrome 的 compositor 驱动 smooth scroll 会静默失效。\n *\n * 改用 `requestAnimationFrame` + easeOutCubic 缓动,直接操作 `scrollTop`,\n * 主线程一次性 400ms 动画,点击触发的单次滚动无感知性能差异。\n *\n * 尊重 `prefers-reduced-motion: reduce`——此时瞬间跳转,无动画。\n */\n\n/** 缓动:easeOutCubic。t ∈ [0, 1]。 */\nfunction easeOutCubic(t: number): number {\n return 1 - (1 - t) * (1 - t) * (1 - t);\n}\n\n/**\n * 平滑滚动(或瞬间跳转)到指定 `data-toc-id` 的标题。\n *\n * @param headingId - TOC item 的 id,对应 DOM 上 `data-toc-id` 属性值\n * @param scrollContainer - 滚动容器(如 `.scrollArea`)\n * @param options - `duration`:动画时长 ms,默认 400\n */\nexport function scrollToTocHeading(\n headingId: string,\n scrollContainer: HTMLElement,\n options?: { duration?: number },\n): void {\n const el = scrollContainer.querySelector<HTMLElement>(\n `[data-toc-id=\"${CSS.escape(headingId)}\"]`,\n );\n if (!el) return;\n\n const startTop = scrollContainer.scrollTop;\n const rootRect = scrollContainer.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const targetTop = startTop + (elRect.top - rootRect.top);\n\n // prefers-reduced-motion:瞬间跳转\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n scrollContainer.scrollTop = targetTop;\n return;\n }\n\n // 手动平滑滚动\n const duration = options?.duration ?? 400;\n const start = performance.now();\n const animate = () => {\n const t = Math.min((performance.now() - start) / duration, 1);\n scrollContainer.scrollTop = startTop + (targetTop - startTop) * easeOutCubic(t);\n if (t < 1) requestAnimationFrame(animate);\n };\n requestAnimationFrame(animate);\n}\n"],"names":["existing"],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
- import { s as stabilizeMarkdown, p as prepareChartMarkdown, b as baseExtensions, a as pureCodeBlock, c as pureImage, d as pureChart, C as CitationRef, m as makeTocGetId, r as renderMathElementHtml, e as extractToc } from "./extractToc-CheLC9kh.js";
2
- import { f, g, l, h, i, j } from "./extractToc-CheLC9kh.js";
3
- import { a as applyCitationSources } from "./ReportContent-CwcppHl8.js";
4
- import { R, e, s } from "./ReportContent-CwcppHl8.js";
1
+ import { s as stabilizeMarkdown, p as prepareChartMarkdown, b as baseExtensions, a as pureCodeBlock, c as pureImage, d as pureChart, C as CitationRef, m as makeTocGetId, r as renderMathElementHtml, e as extractToc } from "./extractToc-BaR6LP1f.js";
2
+ import { f, g, l, h, i, j } from "./extractToc-BaR6LP1f.js";
3
+ import { a as applyCitationSources } from "./ReportContent-MgbebxPV.js";
4
+ import { R, e, s } from "./ReportContent-MgbebxPV.js";
5
5
  import { TableOfContents, generateTocIds } from "@tiptap/extension-table-of-contents";
6
6
  import { MarkdownManager } from "@tiptap/markdown";
7
7
  import { renderToHTMLString } from "@tiptap/static-renderer";
@@ -3,14 +3,14 @@
3
3
 
4
4
  /* 编辑器最外层:查找替换浮动条的粘性范围就是它(超出编辑器范围后浮动条随之离场)。
5
5
  正文的滚动容器仍是 .editorScroll(宿主传的 className 依然落在它身上,契约不变)。 */
6
- ._editorHost_w9lw8_6 {
6
+ ._editorHost_1teg4_6 {
7
7
  position: relative;
8
8
  }
9
9
 
10
10
  /* 浮动条的粘性锚点:高度 0,不占布局、不推挤正文;sticky 让浮动条在「最近的滚动容器」
11
11
  里粘住(宿主的外层滚动容器或页面本身),正文滚动时不会把条子卷上去。
12
12
  注意:锚点必须在 DOM 里排在正文之前——排在后面的话它的自然位置在正文底部,粘性范围就错了。 */
13
- ._findBarAnchor_w9lw8_13 {
13
+ ._findBarAnchor_1teg4_13 {
14
14
  position: sticky;
15
15
  top: 0;
16
16
  height: 0;
@@ -18,16 +18,16 @@
18
18
  }
19
19
 
20
20
  /* 浮动条本体:绝对定位浮在正文之上,具体落点由 findBarOffset 决定(默认右上 4px) */
21
- ._findBar_w9lw8_13 {
21
+ ._findBar_1teg4_13 {
22
22
  position: absolute;
23
23
  }
24
24
 
25
- ._editorScroll_w9lw8_5 {
25
+ ._editorScroll_1teg4_5 {
26
26
  margin-top: 24px;
27
27
  position: relative;
28
28
  }
29
29
 
30
- ._editorContent_w9lw8_30 {
30
+ ._editorContent_1teg4_30 {
31
31
  outline: none;
32
32
  padding: 0;
33
33
  font-family: var(
@@ -49,8 +49,11 @@
49
49
  min-height: var(--tmr-min-height, 420px);
50
50
  }
51
51
 
52
- /* placeholder:空文档第一段显示占位符 */
53
- ._editorContent_w9lw8_30 p.is-editor-empty:first-child::before {
52
+ /* placeholder:空文档的当前文本块显示占位符。
53
+ 属性由官方 Placeholder 扩展(组件里按 placeholder prop 注册)以节点装饰
54
+ 打在段落 / 标题本身上,故此处 attr(data-placeholder) 取得到值。
55
+ 不限定 p:空文档首块是空标题(敲 / 选 H1 后删空)时同样显示。 */
56
+ ._editorContent_1teg4_30 .is-editor-empty:first-child::before {
54
57
  content: attr(data-placeholder);
55
58
  float: left;
56
59
  height: 0;
@@ -58,7 +61,7 @@
58
61
  pointer-events: none;
59
62
  }
60
63
 
61
- ._editorContent_w9lw8_30 h1 {
64
+ ._editorContent_1teg4_30 h1 {
62
65
  font-family: inherit;
63
66
  font-size: 1.55em;
64
67
  font-weight: 700;
@@ -66,7 +69,7 @@
66
69
  line-height: 1.3;
67
70
  }
68
71
 
69
- ._editorContent_w9lw8_30 h2 {
72
+ ._editorContent_1teg4_30 h2 {
70
73
  font-family: inherit;
71
74
  font-size: 1.3em;
72
75
  font-weight: 700;
@@ -74,7 +77,7 @@
74
77
  line-height: 1.3;
75
78
  }
76
79
 
77
- ._editorContent_w9lw8_30 h3 {
80
+ ._editorContent_1teg4_30 h3 {
78
81
  font-family: inherit;
79
82
  font-size: 1.12em;
80
83
  font-weight: 600;
@@ -82,21 +85,21 @@
82
85
  }
83
86
 
84
87
  /* h4-h6:延续 h1-h3 尺寸梯度递减;字号差变小后靠字重保持标题感,h6 字色稍弱。 */
85
- ._editorContent_w9lw8_30 h4 {
88
+ ._editorContent_1teg4_30 h4 {
86
89
  font-family: inherit;
87
90
  font-size: 1.05em;
88
91
  font-weight: 600;
89
92
  margin: 0.7em 0 0.3em;
90
93
  }
91
94
 
92
- ._editorContent_w9lw8_30 h5 {
95
+ ._editorContent_1teg4_30 h5 {
93
96
  font-family: inherit;
94
97
  font-size: 0.95em;
95
98
  font-weight: 600;
96
99
  margin: 0.7em 0 0.3em;
97
100
  }
98
101
 
99
- ._editorContent_w9lw8_30 h6 {
102
+ ._editorContent_1teg4_30 h6 {
100
103
  font-family: inherit;
101
104
  font-size: 0.88em;
102
105
  font-weight: 600;
@@ -104,25 +107,25 @@
104
107
  color: var(--tmr-muted, #777777);
105
108
  }
106
109
 
107
- ._editorContent_w9lw8_30 p {
110
+ ._editorContent_1teg4_30 p {
108
111
  margin: 0.7em 0;
109
112
  }
110
113
 
111
- ._editorContent_w9lw8_30 ul,
112
- ._editorContent_w9lw8_30 ol {
114
+ ._editorContent_1teg4_30 ul,
115
+ ._editorContent_1teg4_30 ol {
113
116
  padding-left: 1.5em;
114
117
  margin: 0.7em 0;
115
118
  }
116
119
 
117
- ._editorContent_w9lw8_30 ul {
120
+ ._editorContent_1teg4_30 ul {
118
121
  list-style: disc;
119
122
  }
120
123
 
121
- ._editorContent_w9lw8_30 ol {
124
+ ._editorContent_1teg4_30 ol {
122
125
  list-style: decimal;
123
126
  }
124
127
 
125
- ._editorContent_w9lw8_30 blockquote {
128
+ ._editorContent_1teg4_30 blockquote {
126
129
  border-left: 3px solid var(--tmr-accent, #ff6719);
127
130
  padding-left: 1em;
128
131
  margin: 0.9em 0;
@@ -130,13 +133,13 @@
130
133
  font-style: italic;
131
134
  }
132
135
 
133
- ._editorContent_w9lw8_30 a {
136
+ ._editorContent_1teg4_30 a {
134
137
  color: var(--tmr-accent, #ff6719);
135
138
  text-decoration: underline;
136
139
  }
137
140
 
138
141
  /* 仅行内代码加灰底;代码块内的 <code>(在 pre 内)由 NodeView 自管,排除掉 */
139
- ._editorContent_w9lw8_30 code:not(pre code) {
142
+ ._editorContent_1teg4_30 code:not(pre code) {
140
143
  background: var(--tmr-code-bg, #f4f4f4);
141
144
  padding: 0.15em 0.4em;
142
145
  border-radius: 4px;
@@ -151,13 +154,13 @@
151
154
  );
152
155
  }
153
156
 
154
- ._editorContent_w9lw8_30 hr {
157
+ ._editorContent_1teg4_30 hr {
155
158
  border: none;
156
159
  border-top: 1px solid var(--tmr-border, #e6e6e6);
157
160
  margin: 1.5em 0;
158
161
  }
159
162
 
160
- ._editorContent_w9lw8_30 img {
163
+ ._editorContent_1teg4_30 img {
161
164
  max-width: 100%;
162
165
  height: auto;
163
166
  border-radius: 6px;
@@ -166,21 +169,21 @@
166
169
  }
167
170
 
168
171
  /* 选中的图片高亮 */
169
- ._editorContent_w9lw8_30 img.ProseMirror-selectednode {
172
+ ._editorContent_1teg4_30 img.ProseMirror-selectednode {
170
173
  outline: 2px solid var(--tmr-accent, #ff6719);
171
174
  }
172
175
 
173
176
  /* 表格:细边框、表头浅灰;外包 .tableWrapper(编辑器 NodeView + SSR renderWrapper)
174
177
  * 桌面:width:100% + 允许换行,整表落在阅读列内(与改前一致)
175
178
  * 窄屏:max-content + nowrap,避免列被挤扁,wrapper 内横滑 */
176
- ._editorContent_w9lw8_30 .tableWrapper {
179
+ ._editorContent_1teg4_30 .tableWrapper {
177
180
  max-width: 100%;
178
181
  overflow-x: auto;
179
182
  -webkit-overflow-scrolling: touch;
180
183
  margin: 1em 0;
181
184
  }
182
185
 
183
- ._editorContent_w9lw8_30 table {
186
+ ._editorContent_1teg4_30 table {
184
187
  border-collapse: collapse;
185
188
  table-layout: auto;
186
189
  width: 100%;
@@ -190,12 +193,12 @@
190
193
  }
191
194
 
192
195
  /* 无 wrapper 的遗留 HTML(旧缓存)仍给一点外边距 */
193
- ._editorContent_w9lw8_30 :not(.tableWrapper) > table {
196
+ ._editorContent_1teg4_30 :not(.tableWrapper) > table {
194
197
  margin: 1em 0;
195
198
  }
196
199
 
197
- ._editorContent_w9lw8_30 table td,
198
- ._editorContent_w9lw8_30 table th {
200
+ ._editorContent_1teg4_30 table td,
201
+ ._editorContent_1teg4_30 table th {
199
202
  border: 1px solid var(--tmr-border, #e6e6e6);
200
203
  padding: 8px 12px;
201
204
  vertical-align: top;
@@ -206,27 +209,27 @@
206
209
  word-break: break-word;
207
210
  }
208
211
 
209
- ._editorContent_w9lw8_30 table th {
212
+ ._editorContent_1teg4_30 table th {
210
213
  background: var(--tmr-table-header-bg, #f7f7f7);
211
214
  font-weight: 600;
212
215
  }
213
216
 
214
217
  @media (max-width: 640px) {
215
- ._editorContent_w9lw8_30 table {
218
+ ._editorContent_1teg4_30 table {
216
219
  width: max-content;
217
220
  min-width: 100%;
218
221
  max-width: none;
219
222
  }
220
223
 
221
- ._editorContent_w9lw8_30 table td,
222
- ._editorContent_w9lw8_30 table th {
224
+ ._editorContent_1teg4_30 table td,
225
+ ._editorContent_1teg4_30 table th {
223
226
  white-space: nowrap;
224
227
  word-break: normal;
225
228
  }
226
229
  }
227
230
 
228
231
  /* 选中的单元格高亮 */
229
- ._editorContent_w9lw8_30 table .selectedCell::after {
232
+ ._editorContent_1teg4_30 table .selectedCell::after {
230
233
  content: '';
231
234
  position: absolute;
232
235
  inset: 0;
@@ -235,7 +238,7 @@
235
238
  }
236
239
 
237
240
  /* 列宽拖拽手柄 */
238
- ._editorContent_w9lw8_30 table .column-resize-handle {
241
+ ._editorContent_1teg4_30 table .column-resize-handle {
239
242
  position: absolute;
240
243
  right: -2px;
241
244
  top: 0;
@@ -248,30 +251,30 @@
248
251
  /* 任务清单:复选框与首行文字在同一行高内垂直居中。
249
252
  li 是 flex 容器,项内段落的外边距不会塌到 li 外(不像普通 ul/ol),只会把正文往下推,
250
253
  所以项内段落清零外边距,项间距改由 li 按 ul/ol 的 0.7em 承担。 */
251
- ._editorContent_w9lw8_30 ul[data-type='taskList'] {
254
+ ._editorContent_1teg4_30 ul[data-type='taskList'] {
252
255
  list-style: none;
253
256
  padding-left: 0.2em;
254
257
  }
255
258
 
256
- ._editorContent_w9lw8_30 ul[data-type='taskList'] li {
259
+ ._editorContent_1teg4_30 ul[data-type='taskList'] li {
257
260
  display: flex;
258
261
  align-items: flex-start;
259
262
  gap: 0.5em;
260
263
  margin: 0.7em 0;
261
264
  }
262
265
 
263
- ._editorContent_w9lw8_30 ul[data-type='taskList'] li > div > p {
266
+ ._editorContent_1teg4_30 ul[data-type='taskList'] li > div > p {
264
267
  margin: 0;
265
268
  }
266
269
 
267
270
  /* 项内第二段起保留半档间距,避免多段任务项的段落粘成一片(首段仍不带外边距) */
268
- ._editorContent_w9lw8_30 ul[data-type='taskList'] li > div > p + p {
271
+ ._editorContent_1teg4_30 ul[data-type='taskList'] li > div > p + p {
269
272
  margin-top: 0.35em;
270
273
  }
271
274
 
272
275
  /* label 撑满一行行高并居中,框心落在首行文字中线上;
273
276
  1lh 即该元素当前行高,随 --tmr-line-height(数字或长度写法)一起变,不靠手调偏移。 */
274
- ._editorContent_w9lw8_30 ul[data-type='taskList'] li > label {
277
+ ._editorContent_1teg4_30 ul[data-type='taskList'] li > label {
275
278
  display: flex;
276
279
  align-items: center;
277
280
  flex: 0 0 auto;
@@ -279,18 +282,18 @@
279
282
  user-select: none;
280
283
  }
281
284
 
282
- ._editorContent_w9lw8_30 ul[data-type='taskList'] li > div {
285
+ ._editorContent_1teg4_30 ul[data-type='taskList'] li > div {
283
286
  flex: 1;
284
287
  }
285
288
 
286
- ._editorContent_w9lw8_30 ul[data-type='taskList'] input[type='checkbox'] {
289
+ ._editorContent_1teg4_30 ul[data-type='taskList'] input[type='checkbox'] {
287
290
  margin: 0;
288
291
  accent-color: var(--tmr-accent, #ff6719);
289
292
  cursor: pointer;
290
293
  }
291
294
 
292
295
  /* 脚注/引文圆标:与正文字垂直居中;配色对齐工具栏 active(浅橙底 + accent 字) */
293
- ._editorContent_w9lw8_30 span.citation-ref {
296
+ ._editorContent_1teg4_30 span.citation-ref {
294
297
  display: inline-flex;
295
298
  align-items: center;
296
299
  justify-content: center;
@@ -327,7 +330,7 @@
327
330
  border-color 0.15s ease;
328
331
  }
329
332
 
330
- ._editorContent_w9lw8_30 span.citation-ref a {
333
+ ._editorContent_1teg4_30 span.citation-ref a {
331
334
  color: inherit;
332
335
  text-decoration: none;
333
336
  display: flex;
@@ -339,26 +342,26 @@
339
342
  pointer-events: none;
340
343
  }
341
344
 
342
- ._editorContent_w9lw8_30 span.citation-ref:hover,
343
- ._editorContent_w9lw8_30 span.citation-ref:focus-within,
344
- ._editorContent_w9lw8_30 span.citation-ref[data-tmr-citation-active] {
345
+ ._editorContent_1teg4_30 span.citation-ref:hover,
346
+ ._editorContent_1teg4_30 span.citation-ref:focus-within,
347
+ ._editorContent_1teg4_30 span.citation-ref[data-tmr-citation-active] {
345
348
  background: var(--tmr-citation-bg-hover, var(--tmr-accent, #ff6719));
346
349
  border-color: var(--tmr-citation-bg-hover, var(--tmr-accent, #ff6719));
347
350
  color: var(--tmr-citation-fg-hover, #ffffff);
348
351
  }
349
352
 
350
- ._editorContent_w9lw8_30 .tiptap-mathematics-render[data-type='inline-math'] {
353
+ ._editorContent_1teg4_30 .tiptap-mathematics-render[data-type='inline-math'] {
351
354
  display: inline;
352
355
  }
353
356
 
354
- ._editorContent_w9lw8_30 .tiptap-mathematics-render[data-type='block-math'] {
357
+ ._editorContent_1teg4_30 .tiptap-mathematics-render[data-type='block-math'] {
355
358
  margin: 0.9em 0;
356
359
  overflow-x: auto;
357
360
  text-align: center;
358
361
  }
359
362
 
360
363
  /* 导入占位:进度写在光标处,不进 Markdown */
361
- ._editorContent_w9lw8_30 .tmr-import-placeholder {
364
+ ._editorContent_1teg4_30 .tmr-import-placeholder {
362
365
  display: flex;
363
366
  align-items: center;
364
367
  gap: 0.5em;
@@ -368,16 +371,16 @@
368
371
  user-select: none;
369
372
  }
370
373
 
371
- ._editorContent_w9lw8_30 .tmr-import-placeholder-spin {
374
+ ._editorContent_1teg4_30 .tmr-import-placeholder-spin {
372
375
  width: 0.7em;
373
376
  height: 0.7em;
374
377
  border: 1.5px solid var(--tmr-border, #e6e6e6);
375
378
  border-top-color: var(--tmr-accent, #ff6719);
376
379
  border-radius: 50%;
377
- animation: _tmr-import-spin_w9lw8_1 0.7s linear infinite;
380
+ animation: _tmr-import-spin_1teg4_1 0.7s linear infinite;
378
381
  }
379
382
 
380
- @keyframes _tmr-import-spin_w9lw8_1 {
383
+ @keyframes _tmr-import-spin_1teg4_1 {
381
384
  to {
382
385
  transform: rotate(360deg);
383
386
  }
@@ -385,7 +388,7 @@
385
388
 
386
389
  /* 快捷键抽屉的悬浮入口:sticky-bottom——自然位置在编辑器底部,
387
390
  内容滚动时保持悬浮在可视区右下;到内容末尾落位对齐右缘 */
388
- ._shortcutFab_w9lw8_388 {
391
+ ._shortcutFab_1teg4_391 {
389
392
  position: sticky;
390
393
  bottom: 20px;
391
394
  z-index: 6;
@@ -406,14 +409,14 @@
406
409
  transition: box-shadow 0.15s, color 0.15s;
407
410
  }
408
411
 
409
- ._shortcutFab_w9lw8_388:hover {
412
+ ._shortcutFab_1teg4_391:hover {
410
413
  color: var(--tmr-accent, #ff6719);
411
414
  box-shadow: 0 8px 24px rgb(0 0 0 / 16%);
412
415
  }
413
416
 
414
417
  /* 宿主容器模式的悬浮键:定位归宿主(如叠在「回到顶部」按钮上方),
415
418
  库只保留按钮本体视觉,不加粘性定位与右下角外边距 */
416
- ._shortcutFabHosted_w9lw8_416 {
419
+ ._shortcutFabHosted_1teg4_419 {
417
420
  position: static;
418
421
  margin: 0;
419
422
  }