ScriptElementTable.tsx 1.5 KB

1234567891011121314151617181920212223242526
  1. "use client";
  2. import { useEffect, useRef } from "react";
  3. import type { ScriptElementRow } from "@/lib/types";
  4. export function ScriptElementTable({ elements, selectedId }: { elements: ScriptElementRow[]; selectedId?: number | string }) {
  5. const selected = useRef<HTMLTableRowElement>(null);
  6. useEffect(() => {
  7. if (typeof selected.current?.scrollIntoView === "function") selected.current.scrollIntoView({ block: "center" });
  8. }, [selectedId]);
  9. return <div className="elementTableViewport" tabIndex={0} aria-label="可滚动的脚本元素表">
  10. <table className="elementTable">
  11. <caption className="srOnly">完整脚本元素表</caption>
  12. <thead><tr><th>元素名称</th><th>一级维度</th><th>二级维度</th><th>使用段落</th></tr></thead>
  13. <tbody>{elements.map((element) => {
  14. const active = String(element.id) === String(selectedId);
  15. return <tr key={String(element.rowId)} ref={active ? selected : undefined} className={active ? "isSelected" : ""}>
  16. <th scope="row">{element.name}</th>
  17. <td>{element.primaryDimension || "—"}</td>
  18. <td>{element.secondaryDimension || "—"}</td>
  19. <td>{element.paragraphs.length ? <ul className="elementParagraphs">{element.paragraphs.map((paragraph) => <li key={String(paragraph.id)}><span>{paragraph.index ? `第 ${paragraph.index} 段` : "段落"}</span>{paragraph.name}</li>)}</ul> : <span className="emptyValue">未关联段落</span>}</td>
  20. </tr>;
  21. })}</tbody>
  22. </table>
  23. </div>;
  24. }