From 99e6b1b81fa38f983e8bf6608c9226e21ca13546 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Fri, 20 Dec 2024 09:35:08 +0100 Subject: [PATCH 1/5] Rename RendermimeMarkdown to MarkdownRenderer --- .../jupyter-chat/src/components/chat-messages.tsx | 4 ++-- ...rendermime-markdown.tsx => markdown-renderer.tsx} | 10 +++++----- packages/jupyter-chat/style/chat.css | 12 ++++++------ ui-tests/tests/chat-file.spec.ts | 6 +++--- ui-tests/tests/message-toolbar.spec.ts | 8 ++++---- ui-tests/tests/send-message.spec.ts | 12 ++++++------ ui-tests/tests/test-utils.ts | 8 ++++---- 7 files changed, 30 insertions(+), 30 deletions(-) rename packages/jupyter-chat/src/components/{rendermime-markdown.tsx => markdown-renderer.tsx} (93%) diff --git a/packages/jupyter-chat/src/components/chat-messages.tsx b/packages/jupyter-chat/src/components/chat-messages.tsx index 1e14da37..109581cb 100644 --- a/packages/jupyter-chat/src/components/chat-messages.tsx +++ b/packages/jupyter-chat/src/components/chat-messages.tsx @@ -17,7 +17,7 @@ import clsx from 'clsx'; import React, { useEffect, useState, useRef, forwardRef } from 'react'; import { ChatInput } from './chat-input'; -import { RendermimeMarkdown } from './rendermime-markdown'; +import { MarkdownRenderer } from './markdown-renderer'; import { ScrollContainer } from './scroll-container'; import { IChatModel } from '../model'; import { IChatMessage, IUser } from '../types'; @@ -391,7 +391,7 @@ export const ChatMessage = forwardRef( hideIncludeSelection={true} /> ) : ( - ( null @@ -122,7 +122,7 @@ function RendermimeMarkdownBase(props: RendermimeMarkdownProps): JSX.Element { }, [props.markdownStr, props.rmRegistry]); return ( -
+
{renderedContent && (appendContent ? (
node && node.appendChild(renderedContent)} /> @@ -146,4 +146,4 @@ function RendermimeMarkdownBase(props: RendermimeMarkdownProps): JSX.Element { ); } -export const RendermimeMarkdown = React.memo(RendermimeMarkdownBase); +export const MarkdownRenderer = React.memo(MarkdownRendererBase); diff --git a/packages/jupyter-chat/style/chat.css b/packages/jupyter-chat/style/chat.css index 1d1420bf..a7ffb936 100644 --- a/packages/jupyter-chat/style/chat.css +++ b/packages/jupyter-chat/style/chat.css @@ -14,7 +14,7 @@ padding: 0 1em; } -.jp-chat-rendermime-markdown { +.jp-chat-rendered-markdown { position: relative; } @@ -26,11 +26,11 @@ * See: https://jupyterlab.readthedocs.io/en/latest/extension/extension_migration.html#css-styling * See also: https://github.com/jupyterlab/jupyter-ai/issues/1090 */ -.jp-ThemedContainer .jp-chat-rendermime-markdown .jp-RenderedHTMLCommon { +.jp-ThemedContainer .jp-chat-rendered-markdown .jp-RenderedHTMLCommon { padding-right: 0; } -.jp-ThemedContainer .jp-chat-rendermime-markdown pre { +.jp-ThemedContainer .jp-chat-rendered-markdown pre { background-color: var(--jp-cell-editor-background); overflow-x: auto; white-space: pre; @@ -39,13 +39,13 @@ border: var(--jp-border-width) solid var(--jp-cell-editor-border-color); } -.jp-ThemedContainer .jp-chat-rendermime-markdown pre > code { +.jp-ThemedContainer .jp-chat-rendered-markdown pre > code { background-color: inherit; overflow-x: inherit; white-space: inherit; } -.jp-ThemedContainer .jp-chat-rendermime-markdown mjx-container { +.jp-ThemedContainer .jp-chat-rendered-markdown mjx-container { font-size: 119%; } @@ -58,7 +58,7 @@ color: var(--jp-ui-font-color3); } -.jp-chat-rendermime-markdown:hover .jp-chat-toolbar { +.jp-chat-rendered-markdown:hover .jp-chat-toolbar { display: inherit; } diff --git a/ui-tests/tests/chat-file.spec.ts b/ui-tests/tests/chat-file.spec.ts index cb9e3535..2fcd72c0 100644 --- a/ui-tests/tests/chat-file.spec.ts +++ b/ui-tests/tests/chat-file.spec.ts @@ -215,7 +215,7 @@ test.describe('#outofband', () => { const updatedContent = 'Content updated'; const chatPanel = await openChat(page, FILENAME); const messageContent = chatPanel - .locator('.jp-chat-messages-container .jp-chat-rendermime-markdown') + .locator('.jp-chat-messages-container .jp-chat-rendered-markdown') .first(); const newMsg = { ...msg, body: updatedContent }; const newContent = { @@ -261,14 +261,14 @@ test.describe('#outofband', () => { await expect(messages).toHaveCount(2); await expect( - messages.last().locator('.jp-chat-rendermime-markdown') + messages.last().locator('.jp-chat-rendered-markdown') ).toHaveText(newMsgContent); }); test('should delete a message from file', async ({ page }) => { const chatPanel = await openChat(page, FILENAME); const messageContent = chatPanel - .locator('.jp-chat-messages-container .jp-chat-rendermime-markdown') + .locator('.jp-chat-messages-container .jp-chat-rendered-markdown') .first(); const newContent = { messages: [], diff --git a/ui-tests/tests/message-toolbar.spec.ts b/ui-tests/tests/message-toolbar.spec.ts index 5685a1b3..bcc1e7c7 100644 --- a/ui-tests/tests/message-toolbar.spec.ts +++ b/ui-tests/tests/message-toolbar.spec.ts @@ -51,7 +51,7 @@ test.describe('#messageToolbar', () => { test('message should have a toolbar', async ({ page }) => { const chatPanel = await openChat(page, FILENAME); const message = chatPanel - .locator('.jp-chat-messages-container .jp-chat-rendermime-markdown') + .locator('.jp-chat-messages-container .jp-chat-rendered-markdown') .first(); await expect(message.locator('.jp-chat-toolbar')).not.toBeVisible(); @@ -66,7 +66,7 @@ test.describe('#messageToolbar', () => { const message = chatPanel .locator('.jp-chat-messages-container .jp-chat-message') .first(); - const messageContent = message.locator('.jp-chat-rendermime-markdown'); + const messageContent = message.locator('.jp-chat-rendered-markdown'); // Should display the message toolbar await messageContent.hover({ position: { x: 5, y: 5 } }); @@ -98,7 +98,7 @@ test.describe('#messageToolbar', () => { const message = chatPanel .locator('.jp-chat-messages-container .jp-chat-message') .first(); - const messageContent = message.locator('.jp-chat-rendermime-markdown'); + const messageContent = message.locator('.jp-chat-rendered-markdown'); // Should display the message toolbar await messageContent.hover({ position: { x: 5, y: 5 } }); @@ -134,7 +134,7 @@ test.describe('#messageToolbar', () => { const message = chatPanel .locator('.jp-chat-messages-container .jp-chat-message') .first(); - const messageContent = message.locator('.jp-chat-rendermime-markdown'); + const messageContent = message.locator('.jp-chat-rendered-markdown'); // Should display the message toolbar await messageContent.hover({ position: { x: 5, y: 5 } }); diff --git a/ui-tests/tests/send-message.spec.ts b/ui-tests/tests/send-message.spec.ts index 11e9eb7a..18c5d2c1 100644 --- a/ui-tests/tests/send-message.spec.ts +++ b/ui-tests/tests/send-message.spec.ts @@ -37,7 +37,7 @@ test.describe('#sendMessages', () => { await expect(messages.locator('.jp-chat-message')).toHaveCount(1); // It seems that the markdown renderer adds a new line. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(MSG_CONTENT + '\n'); }); @@ -53,7 +53,7 @@ test.describe('#sendMessages', () => { await expect(messages.locator('.jp-chat-message')).toHaveCount(1); // It seems that the markdown renderer adds a new line. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(MSG_CONTENT + '\n'); }); @@ -93,7 +93,7 @@ test.describe('#sendMessages', () => { // It seems that the markdown renderer adds a new line, but the '\n' inserter when // pressing Enter above is trimmed. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(MSG_CONTENT + '\n'); }); @@ -139,7 +139,7 @@ test.describe('#sendMessages', () => { // It seems that the markdown renderer adds a new line, but the '\n' inserted when // pressing Enter above is trimmed. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(MSG_CONTENT + '\n'); }); @@ -195,7 +195,7 @@ test.describe('#sendMessages', () => { // It seems that the markdown renderer adds a new line, but the '\n' inserter when // pressing Enter above is trimmed. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(`${MSG_CONTENT}\n${cellContent}\n`); }); @@ -244,7 +244,7 @@ test.describe('#sendMessages', () => { // It seems that the markdown renderer adds a new line, but the '\n' inserter when // pressing Enter above is trimmed. await expect( - messages.locator('.jp-chat-message .jp-chat-rendermime-markdown') + messages.locator('.jp-chat-message .jp-chat-rendered-markdown') ).toHaveText(`${MSG_CONTENT}\nprint\n`); }); }); diff --git a/ui-tests/tests/test-utils.ts b/ui-tests/tests/test-utils.ts index 53b366cd..d1a9dcdc 100644 --- a/ui-tests/tests/test-utils.ts +++ b/ui-tests/tests/test-utils.ts @@ -56,8 +56,8 @@ export const openChat = async ( if (content) { await page.waitForCondition(async () => { const expectedCount = content.messages.length; - const currentCount = await panel?.locator('.jp-chat-rendermime-markdown').count(); - const currentBodies = await panel?.locator('.jp-chat-rendermime-markdown').allTextContents(); + const currentCount = await panel?.locator('.jp-chat-rendered-markdown').count(); + const currentBodies = await panel?.locator('.jp-chat-rendered-markdown').allTextContents(); return expectedCount === currentCount && currentBodies!.every(value => value !== ''); }); } @@ -83,8 +83,8 @@ export const openChatToSide = async ( if (content) { await page.waitForCondition(async () => { const expectedCount = content.messages.length; - const currentCount = await panel?.locator('.jp-chat-rendermime-markdown').count(); - const currentBodies = await panel?.locator('.jp-chat-rendermime-markdown').allTextContents(); + const currentCount = await panel?.locator('.jp-chat-rendered-markdown').count(); + const currentBodies = await panel?.locator('.jp-chat-rendered-markdown').allTextContents(); return expectedCount === currentCount && currentBodies!.every(value => value !== ''); }); } From 9bba33607506bc1abde1fd1e032876e02927a5a0 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Fri, 20 Dec 2024 12:46:44 +0100 Subject: [PATCH 2/5] Export the chat components from @jupyter/chat --- .../jupyter-chat/src/components/code-blocks/index.ts | 2 ++ packages/jupyter-chat/src/components/index.ts | 10 ++++++++++ packages/jupyter-chat/src/components/input/index.ts | 2 ++ .../jupyter-chat/src/components/mui-extras/index.ts | 3 +++ packages/jupyter-chat/src/index.ts | 1 + 5 files changed, 18 insertions(+) create mode 100644 packages/jupyter-chat/src/components/code-blocks/index.ts create mode 100644 packages/jupyter-chat/src/components/index.ts create mode 100644 packages/jupyter-chat/src/components/input/index.ts create mode 100644 packages/jupyter-chat/src/components/mui-extras/index.ts diff --git a/packages/jupyter-chat/src/components/code-blocks/index.ts b/packages/jupyter-chat/src/components/code-blocks/index.ts new file mode 100644 index 00000000..e4054f71 --- /dev/null +++ b/packages/jupyter-chat/src/components/code-blocks/index.ts @@ -0,0 +1,2 @@ +export * from './code-toolbar'; +export * from './copy-button'; diff --git a/packages/jupyter-chat/src/components/index.ts b/packages/jupyter-chat/src/components/index.ts new file mode 100644 index 00000000..7ca89058 --- /dev/null +++ b/packages/jupyter-chat/src/components/index.ts @@ -0,0 +1,10 @@ +export * from './chat'; +export * from './chat-input'; +export * from './chat-input'; +export * from './code-blocks'; +export * from './input'; +export * from './jl-theme-provider'; +export * from './markdown-renderer'; +export * from './mui-extras'; +export * from './scroll-container'; +export * from './toolbar'; diff --git a/packages/jupyter-chat/src/components/input/index.ts b/packages/jupyter-chat/src/components/input/index.ts new file mode 100644 index 00000000..5337477e --- /dev/null +++ b/packages/jupyter-chat/src/components/input/index.ts @@ -0,0 +1,2 @@ +export * from './cancel-button'; +export * from './send-button'; diff --git a/packages/jupyter-chat/src/components/mui-extras/index.ts b/packages/jupyter-chat/src/components/mui-extras/index.ts new file mode 100644 index 00000000..59d91249 --- /dev/null +++ b/packages/jupyter-chat/src/components/mui-extras/index.ts @@ -0,0 +1,3 @@ +export * from './contrasting-tooltip'; +export * from './tooltipped-button'; +export * from './tooltipped-icon-button'; diff --git a/packages/jupyter-chat/src/index.ts b/packages/jupyter-chat/src/index.ts index b5503583..7e084db1 100644 --- a/packages/jupyter-chat/src/index.ts +++ b/packages/jupyter-chat/src/index.ts @@ -4,6 +4,7 @@ */ export * from './active-cell-manager'; +export * from './components'; export * from './icons'; export * from './model'; export * from './registry'; From 9db06d3ae4575318b82a2215c03b5b395b81f5ee Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Fri, 20 Dec 2024 12:48:56 +0100 Subject: [PATCH 3/5] Remove unused component --- .../components/mui-extras/stacking-alert.tsx | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 packages/jupyter-chat/src/components/mui-extras/stacking-alert.tsx diff --git a/packages/jupyter-chat/src/components/mui-extras/stacking-alert.tsx b/packages/jupyter-chat/src/components/mui-extras/stacking-alert.tsx deleted file mode 100644 index dc66bd60..00000000 --- a/packages/jupyter-chat/src/components/mui-extras/stacking-alert.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) Jupyter Development Team. - * Distributed under the terms of the Modified BSD License. - */ - -import React, { useState, useMemo, useCallback } from 'react'; -import { Alert, AlertColor, Collapse } from '@mui/material'; - -export type StackingAlert = { - /** - * A function that triggers an alert. Successive alerts are indicated in the - * JSX element. - * @param alertType Type of alert. - * @param msg Message contained within the alert. - * @returns - */ - show: (alertType: AlertColor, msg: string | Error) => void; - /** - * The Alert JSX element that should be rendered by the consumer. - * This will be `null` if no alerts were triggered. - */ - jsx: JSX.Element | null; - /** - * An async function that closes the alert, and returns a Promise that - * resolves when the onClose animation is completed. - */ - clear: () => void | Promise; -}; - -/** - * Hook that returns a function to trigger an alert, and a corresponding alert - * JSX element for the consumer to render. The number of successive identical - * alerts `X` is indicated in the element via the suffix "(X)". - */ -export function useStackingAlert(): StackingAlert { - const [type, setType] = useState(null); - const [msg, setMsg] = useState(''); - const [repeatCount, setRepeatCount] = useState(0); - const [expand, setExpand] = useState(false); - const [exitPromise, setExitPromise] = useState>(); - const [exitPromiseResolver, setExitPromiseResolver] = useState<() => void>(); - - const showAlert = useCallback( - (nextType: AlertColor, _nextMsg: string | Error) => { - // if the alert is identical to the previous alert, increment the - // `repeatCount` indicator. - const nextMsg = _nextMsg.toString(); - if (nextType === type && nextMsg === msg) { - setRepeatCount(currCount => currCount + 1); - return; - } - - if (type === null) { - // if this alert is being shown for the first time, initialize the - // exitPromise so we can await it on `clear()`. - setExitPromise( - new Promise(res => { - setExitPromiseResolver(() => res); - }) - ); - } - - setType(nextType); - setMsg(nextMsg); - setRepeatCount(0); - setExpand(true); - }, - [msg, type] - ); - - const alertJsx = useMemo( - () => ( - { - exitPromiseResolver?.(); - // only clear the alert after the Collapse exits, otherwise the alert - // disappears without any animation. - setType(null); - setMsg(''); - setRepeatCount(0); - }} - timeout={200} - > - {type !== null && ( - - {msg + (repeatCount ? ` (${repeatCount})` : '')} - - )} - - ), - [msg, repeatCount, type, expand, exitPromiseResolver] - ); - - const clearAlert = useCallback(() => { - setExpand(false); - return exitPromise; - }, [expand, exitPromise]); - - return { - show: showAlert, - jsx: alertJsx, - clear: clearAlert - }; -} From d74edbe15f12260e2f39c2c453db6f1b5c900d0d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 20 Dec 2024 11:55:52 +0000 Subject: [PATCH 4/5] Automatic application of license header --- packages/jupyter-chat/src/components/code-blocks/index.ts | 5 +++++ packages/jupyter-chat/src/components/index.ts | 5 +++++ packages/jupyter-chat/src/components/input/index.ts | 5 +++++ packages/jupyter-chat/src/components/mui-extras/index.ts | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/packages/jupyter-chat/src/components/code-blocks/index.ts b/packages/jupyter-chat/src/components/code-blocks/index.ts index e4054f71..4a5d274a 100644 --- a/packages/jupyter-chat/src/components/code-blocks/index.ts +++ b/packages/jupyter-chat/src/components/code-blocks/index.ts @@ -1,2 +1,7 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + export * from './code-toolbar'; export * from './copy-button'; diff --git a/packages/jupyter-chat/src/components/index.ts b/packages/jupyter-chat/src/components/index.ts index 7ca89058..8e6e920b 100644 --- a/packages/jupyter-chat/src/components/index.ts +++ b/packages/jupyter-chat/src/components/index.ts @@ -1,3 +1,8 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + export * from './chat'; export * from './chat-input'; export * from './chat-input'; diff --git a/packages/jupyter-chat/src/components/input/index.ts b/packages/jupyter-chat/src/components/input/index.ts index 5337477e..3d58f6d3 100644 --- a/packages/jupyter-chat/src/components/input/index.ts +++ b/packages/jupyter-chat/src/components/input/index.ts @@ -1,2 +1,7 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + export * from './cancel-button'; export * from './send-button'; diff --git a/packages/jupyter-chat/src/components/mui-extras/index.ts b/packages/jupyter-chat/src/components/mui-extras/index.ts index 59d91249..f19e50bf 100644 --- a/packages/jupyter-chat/src/components/mui-extras/index.ts +++ b/packages/jupyter-chat/src/components/mui-extras/index.ts @@ -1,3 +1,8 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + export * from './contrasting-tooltip'; export * from './tooltipped-button'; export * from './tooltipped-icon-button'; From 51e56f85b5c9f59b6cff6526d0d731230145b4f9 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Fri, 20 Dec 2024 13:24:49 +0100 Subject: [PATCH 5/5] typo --- packages/jupyter-chat/src/components/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jupyter-chat/src/components/index.ts b/packages/jupyter-chat/src/components/index.ts index 8e6e920b..90352104 100644 --- a/packages/jupyter-chat/src/components/index.ts +++ b/packages/jupyter-chat/src/components/index.ts @@ -5,7 +5,7 @@ export * from './chat'; export * from './chat-input'; -export * from './chat-input'; +export * from './chat-messages'; export * from './code-blocks'; export * from './input'; export * from './jl-theme-provider';