mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-03 22:32:42 +00:00
📊 fix: Contain Markdown Table Overflow (#13543)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Sync Helm Chart Tags / Ignore non-main push (push) Waiting to run
Sync Helm Chart Tags / Sync chart tags (push) Waiting to run
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Sync Helm Chart Tags / Ignore non-main push (push) Waiting to run
Sync Helm Chart Tags / Sync chart tags (push) Waiting to run
* fix: Contain Markdown table overflow * fix: Improve Markdown table scrollbar
This commit is contained in:
parent
4b3fd63803
commit
bede561f10
6 changed files with 73 additions and 3 deletions
|
|
@ -19,7 +19,7 @@ import { ArtifactProvider, CodeBlockProvider } from '~/Providers';
|
|||
import MarkdownErrorBoundary from './MarkdownErrorBoundary';
|
||||
import { langSubset, preprocessLaTeX } from '~/utils';
|
||||
import { unicodeCitation } from '~/components/Web';
|
||||
import { code, a, p, img } from './MarkdownComponents';
|
||||
import { code, a, p, img, table } from './MarkdownComponents';
|
||||
import store from '~/store';
|
||||
|
||||
type TContentProps = {
|
||||
|
|
@ -88,6 +88,7 @@ const Markdown = memo(function Markdown({ content = '', isLatestMessage }: TCont
|
|||
a,
|
||||
p,
|
||||
img,
|
||||
table,
|
||||
artifact: Artifact,
|
||||
citation: Citation,
|
||||
'highlighted-text': HighlightedText,
|
||||
|
|
|
|||
|
|
@ -185,6 +185,19 @@ export const p: React.ElementType = memo(function MarkdownParagraph({ children }
|
|||
});
|
||||
p.displayName = 'MarkdownParagraph';
|
||||
|
||||
type TTableProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const table: React.ElementType = memo(function MarkdownTable({ children }: TTableProps) {
|
||||
return (
|
||||
<div className="markdown-table-wrapper w-full max-w-full">
|
||||
<table>{children}</table>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
table.displayName = 'MarkdownTable';
|
||||
|
||||
type TImageProps = {
|
||||
src?: string;
|
||||
alt?: string;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import supersub from 'remark-supersub';
|
|||
import ReactMarkdown from 'react-markdown';
|
||||
import rehypeHighlight from 'rehype-highlight';
|
||||
import type { PluggableList } from 'unified';
|
||||
import { code, codeNoExecution, a, p } from './MarkdownComponents';
|
||||
import { code, codeNoExecution, a, p, table } from './MarkdownComponents';
|
||||
import { CodeBlockProvider } from '~/Providers';
|
||||
import { langSubset } from '~/utils';
|
||||
|
||||
|
|
@ -72,6 +72,7 @@ class MarkdownErrorBoundary extends React.Component<
|
|||
code: codeExecution ? code : codeNoExecution,
|
||||
a,
|
||||
p,
|
||||
table,
|
||||
} as {
|
||||
[nodeType: string]: React.ElementType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import supersub from 'remark-supersub';
|
|||
import ReactMarkdown from 'react-markdown';
|
||||
import rehypeHighlight from 'rehype-highlight';
|
||||
import type { PluggableList } from 'unified';
|
||||
import { code, codeNoExecution, a, p, img } from './MarkdownComponents';
|
||||
import { code, codeNoExecution, a, p, img, table } from './MarkdownComponents';
|
||||
import { CodeBlockProvider, ArtifactProvider } from '~/Providers';
|
||||
import MarkdownErrorBoundary from './MarkdownErrorBoundary';
|
||||
import { langSubset } from '~/utils';
|
||||
|
|
@ -44,6 +44,7 @@ const MarkdownLite = memo(
|
|||
a,
|
||||
p,
|
||||
img,
|
||||
table,
|
||||
} as {
|
||||
[nodeType: string]: React.ElementType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import Markdown from '../Markdown';
|
||||
import MarkdownLite from '../MarkdownLite';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { UI_RESOURCE_MARKER } from '~/components/MCPUIResource/plugin';
|
||||
import {
|
||||
|
|
@ -108,3 +109,35 @@ describe('Markdown with MCP UI markers (resource IDs)', () => {
|
|||
expect(renderers[1]).toHaveAttribute('data-resource-uri', 'ui://weather/nyc');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Markdown table rendering', () => {
|
||||
const tableMarkdown = [
|
||||
'| Alpha | Bravo | Charlie | Delta | Echo | Foxtrot | Golf | Hotel |',
|
||||
'| --- | --- | --- | --- | --- | --- | --- | --- |',
|
||||
'| one | two | three | four | five | six | seven | eight |',
|
||||
].join('\n');
|
||||
|
||||
it('wraps GFM tables in a horizontally scrollable container', () => {
|
||||
render(
|
||||
<RecoilRoot>
|
||||
<Markdown content={tableMarkdown} isLatestMessage={false} />
|
||||
</RecoilRoot>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('table').parentElement).toHaveClass(
|
||||
'markdown-table-wrapper',
|
||||
'w-full',
|
||||
'max-w-full',
|
||||
);
|
||||
});
|
||||
|
||||
it('wraps lightweight Markdown tables in a horizontally scrollable container', () => {
|
||||
render(<MarkdownLite content={tableMarkdown} />);
|
||||
|
||||
expect(screen.getByRole('table').parentElement).toHaveClass(
|
||||
'markdown-table-wrapper',
|
||||
'w-full',
|
||||
'max-w-full',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1496,6 +1496,27 @@ button {
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.markdown-table-wrapper {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
padding-bottom: 0.25rem;
|
||||
scrollbar-color: var(--border-medium) transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.markdown-table-wrapper::-webkit-scrollbar {
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown-table-wrapper::-webkit-scrollbar-thumb {
|
||||
background-color: var(--border-medium);
|
||||
}
|
||||
|
||||
.markdown-table-wrapper::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--border-heavy);
|
||||
}
|
||||
|
||||
/* Show scrollbar only on hover */
|
||||
.scrollbar-hover {
|
||||
scrollbar-width: thin;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue