diff --git a/.changeset/change-history-label-and-scrollbar.md b/.changeset/change-history-label-and-scrollbar.md new file mode 100644 index 00000000..42e84814 --- /dev/null +++ b/.changeset/change-history-label-and-scrollbar.md @@ -0,0 +1,12 @@ +--- +'@doc-kit/generator-react': patch +--- + +Fix `[object Object]` in ChangeHistory aria-label and dropdown horizontal scrollbar + +- Change history labels were passing a JSX AST object instead of a plain text + string to the `ChangeHistory` component, causing `aria-label` to render as + `[object Object]`. Labels are now extracted as plain text via `remark-parse`. +- The ChangeHistory dropdown could show a horizontal scrollbar when label text + overflowed the fixed-width container. Added `overflow-wrap` and `word-break` + rules to prevent this. diff --git a/packages/react/src/html/ui/index.css b/packages/react/src/html/ui/index.css index 3af0f65c..54f1445a 100644 --- a/packages/react/src/html/ui/index.css +++ b/packages/react/src/html/ui/index.css @@ -120,6 +120,12 @@ main { div[role='menu'] { left: 0; + + /* Prevent long labels from overflowing dropdown width */ + a[role='menuitem'] div { + overflow-wrap: anywhere; + word-break: break-word; + } } } } diff --git a/packages/react/src/jsx-ast/utils/buildContent.mjs b/packages/react/src/jsx-ast/utils/buildContent.mjs index bc92b7be..7b9a7dda 100644 --- a/packages/react/src/jsx-ast/utils/buildContent.mjs +++ b/packages/react/src/jsx-ast/utils/buildContent.mjs @@ -8,9 +8,12 @@ import { } from '@doc-kit/core/utils/configuration/templates.mjs'; import { omitKeys } from '@doc-kit/core/utils/misc.mjs'; import { UNIST } from '@doc-kit/core/utils/queries/index.mjs'; +import { transformNodesToString } from '@doc-kit/core/utils/unist.mjs'; import { h as createElement } from 'hastscript'; import { slice } from 'mdast-util-slice-markdown'; import readingTime from 'reading-time'; +import remarkParse from 'remark-parse'; +import { unified } from 'unified'; import { u as createTree } from 'unist-builder'; import { SKIP, visit } from 'unist-util-visit'; @@ -35,6 +38,18 @@ import { getFullName, } from './signature.mjs'; +/** + * Converts a markdown string to plain text by parsing it and extracting + * text and inline code values. + * + * @param {string} markdown - The markdown string to convert. + * @returns {string} The plain text representation. + */ +const toPlainText = markdown => + transformNodesToString( + unified().use(remarkParse).parse(markdown).children + ).trim(); + /** * Processes lifecycle and change history data into a sorted array of change entries. * @param {import('@doc-kit/core/generators/metadata/types').MetadataEntry} entry - The metadata entry @@ -48,11 +63,10 @@ export const gatherChangeEntries = entry => { label: `${label}: ${enforceArray(entry[field]).join(', ')}`, })); - // Explicit changes with parsed JSX labels + // Explicit changes with plain-text labels extracted from markdown const explicitChanges = (entry.changes || []).map(change => ({ versions: enforceArray(change.version), - label: remark().runSync(remark().parse(change.description)).body[0] - .expression, + label: toPlainText(change.description), url: change['pr-url'], }));