( runtimeRef: React.RefObject<MarkdownRuntime>, interactive = true, mediaInset = false, )
| 1528 | } |
| 1529 | |
| 1530 | function createMarkdownComponents( |
| 1531 | runtimeRef: React.RefObject<MarkdownRuntime>, |
| 1532 | interactive = true, |
| 1533 | mediaInset = false, |
| 1534 | ): Components { |
| 1535 | const listItemClassName = "[&_p]:inline"; |
| 1536 | const listClassName = "space-y-1 pl-6 marker:text-muted-foreground/80"; |
| 1537 | |
| 1538 | return { |
| 1539 | spoiler: ({ |
| 1540 | children, |
| 1541 | ...props |
| 1542 | }: { |
| 1543 | "data-block-spoiler"?: string; |
| 1544 | children?: React.ReactNode; |
| 1545 | }) => ( |
| 1546 | <SpoilerInline |
| 1547 | block={props["data-block-spoiler"] != null} |
| 1548 | interactive={interactive} |
| 1549 | > |
| 1550 | {children} |
| 1551 | </SpoilerInline> |
| 1552 | ), |
| 1553 | a: ({ children, href, ...props }) => { |
| 1554 | const { imetaByUrl, onOpenMessageLink } = runtimeRef.current; |
| 1555 | if (!interactive) { |
| 1556 | return <span className="font-medium text-current">{children}</span>; |
| 1557 | } |
| 1558 | |
| 1559 | // Markdown image-link syntax (`[](href)`) otherwise nests the |
| 1560 | // image lightbox button inside an anchor. Keep the image as the lightbox |
| 1561 | // trigger and suppress the parent link activation for block media. |
| 1562 | if (hasBlockMedia(React.Children.toArray(children))) { |
| 1563 | return <>{children}</>; |
| 1564 | } |
| 1565 | |
| 1566 | const label = getReactNodeText(children); |
| 1567 | |
| 1568 | // Generic file attachment: a `[filename](url)` link whose href matches an |
| 1569 | // imeta entry with a non-image, non-video MIME. Render a download card |
| 1570 | // instead of a plain link. (Media uses the `img` renderer, not this path.) |
| 1571 | const card = resolveFileCard( |
| 1572 | href ? imetaByUrl?.get(href) : undefined, |
| 1573 | href, |
| 1574 | label, |
| 1575 | ); |
| 1576 | if (card) { |
| 1577 | return ( |
| 1578 | <FileCard |
| 1579 | href={card.href} |
| 1580 | filename={card.filename} |
| 1581 | size={card.size} |
| 1582 | /> |
| 1583 | ); |
| 1584 | } |
| 1585 | |
| 1586 | // Intercept `buzz://message?channel=…&id=…` links so a click navigates |
| 1587 | // in-app instead of opening the URL in the OS browser. http(s) links |
no test coverage detected