diff --git a/CHANGELOG.md b/CHANGELOG.md index c0f6709a31..b93cd09319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/ - Improved drop zone behavior and styling in Fluent theme, in PR [#5328](https://github.com/microsoft/BotFramework-WebChat/pull/5328), by [@OEvgeny](https://github.com/OEvgeny) - Excluded side effects from module entry points to prevent global scope modifications, in PR [#5329](https://github.com/microsoft/BotFramework-WebChat/pull/5329), by [@OEvgeny](https://github.com/OEvgeny) - Moved to `micromark` for rendering Markdown, instead of `markdown-it`, in PR [#5330](https://github.com/microsoft/BotFramework-WebChat/pull/5330), by [@compulim](https://github.com/compulim) +- Improved view code dialog UI in Fluent theme with better styling and accessibility, in PR [#5337](https://github.com/microsoft/BotFramework-WebChat/pull/5337), by [@OEvgeny](https://github.com/OEvgeny) ### Fixed diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-5-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-5-snap.png index 7a22155044..ce4149fcae 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-5-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-5-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-6-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-6-snap.png index 7201ab4642..3966ce7ab1 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-6-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-6-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-7-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-7-snap.png index 0ca06ad684..3a101218f3 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-7-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-fluent-right-fluent-7-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png new file mode 100644 index 0000000000..0b6193e6fb Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png new file mode 100644 index 0000000000..96fc77ff62 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png new file mode 100644 index 0000000000..ea87fed004 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png new file mode 100644 index 0000000000..8f96e8baf7 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png new file mode 100644 index 0000000000..0b6193e6fb Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png new file mode 100644 index 0000000000..96fc77ff62 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png new file mode 100644 index 0000000000..851f9a1e76 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png new file mode 100644 index 0000000000..8f96e8baf7 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-5-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-5-snap.png index d0406837f1..6ca9c5577f 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-5-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-5-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-6-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-6-snap.png index 8bfc0a9128..fd0a4b497a 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-6-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-6-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-7-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-7-snap.png index d0406837f1..6ca9c5577f 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-7-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-pre-chat-message-7-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-13-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-13-snap.png index f1f9c6892b..fb78f31fe0 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-13-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-13-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-14-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-14-snap.png index 4257b5e581..2dcd63f441 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-14-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-14-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-15-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-15-snap.png index 89b13c67ef..7ae71df301 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-15-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-15-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-5-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-5-snap.png index a19e96afe3..17e13777e2 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-5-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-5-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-6-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-6-snap.png index 6c843bf36b..be21567518 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-6-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-6-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-7-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-7-snap.png index 65cd263e5b..57552d31ee 100644 Binary files a/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-7-snap.png and b/__tests__/__image_snapshots__/html/side-by-side-wide-dark-js-fluent-theme-applied-dark-theme-applied-side-by-side-left-transcript-right-transcript-7-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png new file mode 100644 index 0000000000..4668432512 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png new file mode 100644 index 0000000000..cf31297d70 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-2-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png new file mode 100644 index 0000000000..7fb56a3e8e Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-3-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png new file mode 100644 index 0000000000..1cf411ee19 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-4-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png new file mode 100644 index 0000000000..4668432512 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png new file mode 100644 index 0000000000..cf31297d70 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-2-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png new file mode 100644 index 0000000000..67626f3be8 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-3-snap.png differ diff --git a/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png new file mode 100644 index 0000000000..1cf411ee19 Binary files /dev/null and b/__tests__/__image_snapshots__/html/side-by-side-wide-js-fluent-theme-applied-side-by-side-left-transcript-right-codeblock-dark-4-snap.png differ diff --git a/__tests__/html/fluentTheme/side-by-side.wide.dark.html b/__tests__/html/fluentTheme/side-by-side.wide.dark.html index 8e8af513fb..2485974b95 100644 --- a/__tests__/html/fluentTheme/side-by-side.wide.dark.html +++ b/__tests__/html/fluentTheme/side-by-side.wide.dark.html @@ -73,10 +73,17 @@ let timestampStart = new Date(2020, 7, 9).getTime(); const timestamp = () => new Date(timestampStart += 100).toISOString(); - const [leftTranscriptIndex = 0, rightTranscriptIndex = 1] = new URLSearchParams(location.search).getAll('transcript'); - const [leftVariant = 'fluent', rightVariant = 'copilot'] = new URLSearchParams(location.search).getAll('variant'); + const searchParams = new URLSearchParams(location.search); - const sendBoxIndexes = new URLSearchParams(location.search).getAll('focus'); + const [leftTranscriptIndex = 0, rightTranscriptIndex = 1] = searchParams.getAll('transcript'); + const [leftVariant = 'fluent', rightVariant = 'copilot'] = searchParams.getAll('variant'); + + const sendBoxIndexes = searchParams.getAll('focus'); + const activeFocusPresets = searchParams.getAll('focus-preset'); + + const adjustStyleOptions = Object.fromEntries(['codeBlockTheme'] + .map(key => [key, searchParams.get(key)]) + .filter(([key, value]) => value)); const botIcon = 'data:image/png;base64,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'; @@ -94,6 +101,27 @@ } }; + const waveSvg = `data:image/svg+xml;utf8,${encodeURIComponent(` + + + + + + + + + + + + + + + +`)}`; + const transcripts = [[ { timestamp: timestamp(), @@ -511,6 +539,63 @@ streamSequence: 99 } } + ], [ + { + timestamp: timestamp(), + from: { role: 'bot' }, + entities: [{ + ...aiMessageEntity, + isBasedOn: { + '@type': 'SoftwareSourceCode', + 'programmingLanguage': 'python', + "text": `import numpy as np +import matplotlib.pyplot as plt + +def plot_sine_waves(): + """Create a beautiful visualization of sine waves with different frequencies.""" + # Generate time points + t = np.linspace(0, 10, 1000) + + # Create waves with different frequencies and phases + wave1 = np.sin(t) + wave2 = 0.5 * np.sin(2 * t + np.pi/4) + wave3 = 0.3 * np.sin(3 * t + np.pi/3) + + # Combine waves + combined = wave1 + wave2 + wave3 + + # Create a stylish plot + plt.style.use('seaborn-darkgrid') + plt.figure(figsize=(12, 8)) + + # Plot individual waves + plt.plot(t, wave1, label='Primary Wave', alpha=0.5) + plt.plot(t, wave2, label='Second Harmonic', alpha=0.5) + plt.plot(t, wave3, label='Third Harmonic', alpha=0.5) + + # Plot combined wave with a thicker line + plt.plot(t, combined, 'r-', + label='Combined Wave', + linewidth=2) + + plt.title('Harmonic Wave Composition', fontsize=14) + plt.xlabel('Time', fontsize=12) + plt.ylabel('Amplitude', fontsize=12) + plt.legend() + plt.grid(True, alpha=0.3) + + # Show the plot + plt.tight_layout() + plt.show() + +# Generate the visualization +plot_sine_waves()` + } + }], + id: "a4c0c01d-c06e-4dde-9278-265c607b545b-82", + type: "message", + text: `This example demonstrates creating a beautiful visualization of harmonic waves using Python's Matplotlib library. The code generates three sine waves with different frequencies and phases, then combines them to show wave interference patterns.\nwave plot`, + } ]]; const leftStore = testHelpers.createStore(); @@ -557,7 +642,8 @@ TEXT_INPUT_PLACEHOLDER: 'Describe how your copilot should behave' }} styleOptions={{ - maxMessageLength: null + maxMessageLength: null, + ...adjustStyleOptions }} /> @@ -568,12 +654,14 @@ directLine={rightDirectLine} store={rightStore} overrideLocalizedStrings={{ - TEXT_INPUT_PLACEHOLDER: 'Ask a work question or use / to reference people, files and more' + TEXT_INPUT_PLACEHOLDER: 'Ask a work question or use / to reference people, files and more', + ACTIVITY_CODE_CAUTION: 'AI-generated code. Review and use carefully. [More info on FAQ](https://aka.ms/AIandCopilotFAQs).' }} styleOptions={{ groupTimestamp: 1, timestampFormat: 'absolute', - botAvatarBackgroundColor: '#304E7A' + botAvatarBackgroundColor: '#304E7A', + ...adjustStyleOptions }} /> @@ -586,30 +674,56 @@ await host.snapshot(); - const sendboxes = Array.from(document.querySelectorAll(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)).filter((_, index) => sendBoxIndexes.includes(String(index))); - - for (const sendbox of sendboxes) { - sendbox.focus(); - await host.sendKeys('Next message'); - await host.snapshot(); - await host.sendKeys('ENTER'); - // hide timestamp to not fail snapshot if is not relative - sendbox.parentElement.parentElement.parentElement.parentElement.querySelector('.webchat__basic-transcript__activity:last-child .webchat__stacked-layout__status').style.opacity = 0 - await host.snapshot(); - await host.sendShiftTab(); - await host.snapshot(); - await host.sendKeys('HOME'); - await host.snapshot(); - await host.sendKeys('END'); - await host.snapshot(); - await host.sendKeys('ARROW_UP'); - await host.snapshot(); - await host.sendKeys('ENTER'); - await host.sendShiftTab(); - await host.snapshot(); - await host.sendKeys('ENTER'); - await host.snapshot(); - await host.sendKeys('ESCAPE'); + const focusPresetsMap = new Map(Object.entries({ + navigation: async sendbox => { + sendbox.focus(); + await host.sendKeys('Next message'); + await host.snapshot(); + await host.sendKeys('ENTER'); + // hide timestamp to not fail snapshot if is not relative + sendbox.parentElement.parentElement.parentElement.parentElement.querySelector('.webchat__basic-transcript__activity:last-child .webchat__stacked-layout__status').style.opacity = 0 + await host.snapshot(); + await host.sendShiftTab(); + await host.snapshot(); + await host.sendKeys('HOME'); + await host.snapshot(); + await host.sendKeys('END'); + await host.snapshot(); + await host.sendKeys('ARROW_UP'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.sendShiftTab(); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ESCAPE'); + }, + viewCode: async sendbox => { + sendbox.focus(); + await host.sendShiftTab(); + await host.sendKeys('ARROW_UP'); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + } + })); + + const sendboxes = Array.from(document.querySelectorAll(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)) + .filter((_, index) => sendBoxIndexes.includes(String(index))); + + const focusPresets = activeFocusPresets + .map(presetName => focusPresetsMap.get(presetName)) + .filter(preset => preset) + + if (!focusPresets.length) focusPresets.push(focusPresetsMap.get('navigation')); + + for (const preset of focusPresets) { + for (const sendbox of sendboxes) { + await preset(sendbox) + } } }); // TODO: unskip and try ShadowDOM when we get support diff --git a/__tests__/html/fluentTheme/side-by-side.wide.dark.js b/__tests__/html/fluentTheme/side-by-side.wide.dark.js index b7a645dec5..464c432f78 100644 --- a/__tests__/html/fluentTheme/side-by-side.wide.dark.js +++ b/__tests__/html/fluentTheme/side-by-side.wide.dark.js @@ -14,5 +14,9 @@ describe('Fluent theme applied', () => { runHTML('fluentTheme/side-by-side.wide.dark?transcript=0&transcript=4')); test('side by side left - fluent, right - fluent', () => runHTML('fluentTheme/side-by-side.wide.dark?transcript=0&transcript=2&focus=1&variant=fluent&variant=fluent')); + test('side by side left - transcript, right - codeblock', () => + runHTML('fluentTheme/side-by-side.wide.dark?transcript=0&transcript=5&focus=1&focus-preset=viewCode')); + test('side by side left - transcript, right - codeblock dark', () => + runHTML('fluentTheme/side-by-side.wide.dark?transcript=0&transcript=5&focus=1&focus-preset=viewCode&codeBlockTheme=github-dark-default')); }); }); diff --git a/__tests__/html/fluentTheme/side-by-side.wide.html b/__tests__/html/fluentTheme/side-by-side.wide.html index d3f116ab62..b1a165a264 100644 --- a/__tests__/html/fluentTheme/side-by-side.wide.html +++ b/__tests__/html/fluentTheme/side-by-side.wide.html @@ -82,10 +82,18 @@ let timestampStart = new Date(2020, 7, 9).getTime(); const timestamp = () => new Date(timestampStart += 100).toISOString(); - const [leftTranscriptIndex = 0, rightTranscriptIndex = 1] = new URLSearchParams(location.search).getAll('transcript'); - const [leftVariant = 'fluent', rightVariant = 'copilot'] = new URLSearchParams(location.search).getAll('variant'); - const sendBoxIndexes = new URLSearchParams(location.search).getAll('focus'); + const searchParams = new URLSearchParams(location.search); + + const [leftTranscriptIndex = 0, rightTranscriptIndex = 1] = searchParams.getAll('transcript'); + const [leftVariant = 'fluent', rightVariant = 'copilot'] = searchParams.getAll('variant'); + + const sendBoxIndexes = searchParams.getAll('focus'); + const activeFocusPresets = searchParams.getAll('focus-preset'); + + const adjustStyleOptions = Object.fromEntries(['codeBlockTheme'] + .map(key => [key, searchParams.get(key)]) + .filter(([key, value]) => value)); const botIcon = 'data:image/png;base64,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'; @@ -103,6 +111,27 @@ } }; + const waveSvg = `data:image/svg+xml;utf8,${encodeURIComponent(` + + + + + + + + + + + + + + + +`)}`; + const transcripts = [[ { timestamp: timestamp(), @@ -520,6 +549,63 @@ streamSequence: 99 } } + ], [ + { + timestamp: timestamp(), + from: { role: 'bot' }, + entities: [{ + ...aiMessageEntity, + isBasedOn: { + '@type': 'SoftwareSourceCode', + 'programmingLanguage': 'python', + "text": `import numpy as np +import matplotlib.pyplot as plt + +def plot_sine_waves(): + """Create a beautiful visualization of sine waves with different frequencies.""" + # Generate time points + t = np.linspace(0, 10, 1000) + + # Create waves with different frequencies and phases + wave1 = np.sin(t) + wave2 = 0.5 * np.sin(2 * t + np.pi/4) + wave3 = 0.3 * np.sin(3 * t + np.pi/3) + + # Combine waves + combined = wave1 + wave2 + wave3 + + # Create a stylish plot + plt.style.use('seaborn-darkgrid') + plt.figure(figsize=(12, 8)) + + # Plot individual waves + plt.plot(t, wave1, label='Primary Wave', alpha=0.5) + plt.plot(t, wave2, label='Second Harmonic', alpha=0.5) + plt.plot(t, wave3, label='Third Harmonic', alpha=0.5) + + # Plot combined wave with a thicker line + plt.plot(t, combined, 'r-', + label='Combined Wave', + linewidth=2) + + plt.title('Harmonic Wave Composition', fontsize=14) + plt.xlabel('Time', fontsize=12) + plt.ylabel('Amplitude', fontsize=12) + plt.legend() + plt.grid(True, alpha=0.3) + + # Show the plot + plt.tight_layout() + plt.show() + +# Generate the visualization +plot_sine_waves()` + } + }], + id: "a4c0c01d-c06e-4dde-9278-265c607b545b-82", + type: "message", + text: `This example demonstrates creating a beautiful visualization of harmonic waves using Python's Matplotlib library. The code generates three sine waves with different frequencies and phases, then combines them to show wave interference patterns.\nwave plot`, + } ]]; const leftStore = testHelpers.createStore(); @@ -538,7 +624,8 @@ TEXT_INPUT_PLACEHOLDER: 'Describe how your copilot should behave' }} styleOptions={{ - maxMessageLength: null + maxMessageLength: null, + ...adjustStyleOptions }} /> @@ -549,12 +636,14 @@ directLine={rightDirectLine} store={rightStore} overrideLocalizedStrings={{ - TEXT_INPUT_PLACEHOLDER: 'Ask a work question or use / to reference people, files and more' + TEXT_INPUT_PLACEHOLDER: 'Ask a work question or use / to reference people, files and more', + ACTIVITY_CODE_CAUTION: 'AI-generated code. Review and use carefully. [More info on FAQ](https://aka.ms/AIandCopilotFAQs).' }} styleOptions={{ groupTimestamp: 1, timestampFormat: 'absolute', botAvatarBackgroundColor: '#304E7A', + ...adjustStyleOptions }} /> @@ -568,30 +657,56 @@ await host.snapshot(); - const sendboxes = Array.from(document.querySelectorAll(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)).filter((_, index) => sendBoxIndexes.includes(String(index))); - - for (const sendbox of sendboxes) { - sendbox.focus(); - await host.sendKeys('Next message'); - await host.snapshot(); - await host.sendKeys('ENTER'); - // hide timestamp to not fail snapshot if is not relative - sendbox.parentElement.parentElement.parentElement.parentElement.querySelector('.webchat__basic-transcript__activity:last-child .webchat__stacked-layout__status').style.opacity = 0 - await host.snapshot(); - await host.sendShiftTab(); - await host.snapshot(); - await host.sendKeys('HOME'); - await host.snapshot(); - await host.sendKeys('END'); - await host.snapshot(); - await host.sendKeys('ARROW_UP'); - await host.snapshot(); - await host.sendKeys('ENTER'); - await host.sendShiftTab(); - await host.snapshot(); - await host.sendKeys('ENTER'); - await host.snapshot(); - await host.sendKeys('ESCAPE'); + const focusPresetsMap = new Map(Object.entries({ + navigation: async sendbox => { + sendbox.focus(); + await host.sendKeys('Next message'); + await host.snapshot(); + await host.sendKeys('ENTER'); + // hide timestamp to not fail snapshot if is not relative + sendbox.parentElement.parentElement.parentElement.parentElement.querySelector('.webchat__basic-transcript__activity:last-child .webchat__stacked-layout__status').style.opacity = 0 + await host.snapshot(); + await host.sendShiftTab(); + await host.snapshot(); + await host.sendKeys('HOME'); + await host.snapshot(); + await host.sendKeys('END'); + await host.snapshot(); + await host.sendKeys('ARROW_UP'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.sendShiftTab(); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ESCAPE'); + }, + viewCode: async sendbox => { + sendbox.focus(); + await host.sendShiftTab(); + await host.sendKeys('ARROW_UP'); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + await host.sendKeys('ENTER'); + await host.snapshot(); + } + })); + + const sendboxes = Array.from(document.querySelectorAll(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)) + .filter((_, index) => sendBoxIndexes.includes(String(index))); + + const focusPresets = activeFocusPresets + .map(presetName => focusPresetsMap.get(presetName)) + .filter(preset => preset) + + if (!focusPresets.length) focusPresets.push(focusPresetsMap.get('navigation')); + + for (const preset of focusPresets) { + for (const sendbox of sendboxes) { + await preset(sendbox) + } } }); // TODO: unskip and try ShadowDOM when we get support diff --git a/__tests__/html/fluentTheme/side-by-side.wide.js b/__tests__/html/fluentTheme/side-by-side.wide.js index 690b516590..06f0a39000 100644 --- a/__tests__/html/fluentTheme/side-by-side.wide.js +++ b/__tests__/html/fluentTheme/side-by-side.wide.js @@ -13,4 +13,8 @@ describe('Fluent theme applied', () => { runHTML('fluentTheme/side-by-side.wide?transcript=0&transcript=4')); test('side by side left - fluent, right - fluent', () => runHTML('fluentTheme/side-by-side.wide?transcript=0&transcript=2&focus=1&variant=fluent&variant=fluent')); + test('side by side left - transcript, right - codeblock', () => + runHTML('fluentTheme/side-by-side.wide?transcript=0&transcript=5&focus=1&focus-preset=viewCode')); + test('side by side left - transcript, right - codeblock dark', () => + runHTML('fluentTheme/side-by-side.wide?transcript=0&transcript=5&focus=1&focus-preset=viewCode&codeBlockTheme=github-dark-default')); }); diff --git a/packages/api/src/StyleOptions.ts b/packages/api/src/StyleOptions.ts index 867a493eac..77a7c41687 100644 --- a/packages/api/src/StyleOptions.ts +++ b/packages/api/src/StyleOptions.ts @@ -916,6 +916,18 @@ type StyleOptions = { * New in 4.19.0. */ borderAnimationColor3?: string; + + /** + * Code block theme + * + * - `'github-light-default'` - use light theme for code blocks + * - `'github-dark-default'` - use dark theme for code blocks + * + * @default 'github-light-default' + * + * New in 4.19.0. + */ + codeBlockTheme?: 'github-light-default' | 'github-dark-default'; }; // StrictStyleOptions is only used internally in Web Chat and for simplifying our code: diff --git a/packages/api/src/defaultStyleOptions.ts b/packages/api/src/defaultStyleOptions.ts index f797acf47a..ec3147fcbd 100644 --- a/packages/api/src/defaultStyleOptions.ts +++ b/packages/api/src/defaultStyleOptions.ts @@ -303,7 +303,9 @@ const DEFAULT_OPTIONS: Required = { // Border animation borderAnimationColor1: '#203C91', borderAnimationColor2: '#4DD3FF', - borderAnimationColor3: '#2B8DD8' + borderAnimationColor3: '#2B8DD8', + + codeBlockTheme: 'github-light-default' as const }; export default DEFAULT_OPTIONS; diff --git a/packages/component/src/Attachment/Text/private/ActivityViewCodeButton.tsx b/packages/component/src/Attachment/Text/private/ActivityViewCodeButton.tsx index 6d6efd09c7..a34be6d48f 100644 --- a/packages/component/src/Attachment/Text/private/ActivityViewCodeButton.tsx +++ b/packages/component/src/Attachment/Text/private/ActivityViewCodeButton.tsx @@ -31,10 +31,7 @@ const ViewCodeButton = ({ className, code, language, title = '', isAIGenerated = {isAIGenerated && (
- +
)}
diff --git a/packages/component/src/Attachment/Text/private/CodeContent.tsx b/packages/component/src/Attachment/Text/private/CodeContent.tsx index 262a59f06e..f39c4a2be5 100644 --- a/packages/component/src/Attachment/Text/private/CodeContent.tsx +++ b/packages/component/src/Attachment/Text/private/CodeContent.tsx @@ -13,11 +13,12 @@ type Props = Readonly<{ title: string; }>; -const { useLocalizer } = hooks; +const { useLocalizer, useStyleOptions } = hooks; const highlighterPromise = createHighlighter(); const CodeContent = memo(({ children, className, code, language, title }: Props) => { + const [{ codeBlockTheme }] = useStyleOptions(); const [highlightedCode, setHighlightedCode] = useState(''); const localize = useLocalizer(); @@ -35,7 +36,7 @@ const CodeContent = memo(({ children, className, code, language, title }: Props) try { const html = highlighter.codeToHtml(code, { lang: language, - theme: 'github-light-default' + theme: codeBlockTheme }); setHighlightedCode(html); @@ -52,7 +53,7 @@ const CodeContent = memo(({ children, className, code, language, title }: Props) return () => { mounted = false; }; - }, [code, language]); + }, [code, codeBlockTheme, language]); return ( diff --git a/packages/component/src/Attachment/Text/private/shiki.ts b/packages/component/src/Attachment/Text/private/shiki.ts index 5a083989a5..51da75ac95 100644 --- a/packages/component/src/Attachment/Text/private/shiki.ts +++ b/packages/component/src/Attachment/Text/private/shiki.ts @@ -1,5 +1,5 @@ // `shiki/core` entry does not include any themes or languages or the wasm binary. -import { createHighlighterCore } from 'shiki/core'; +import { createHighlighterCore, type ThemeRegistrationRaw } from 'shiki/core'; import { createJavaScriptRegexEngine } from 'shiki/engine-javascript.mjs'; // directly import the theme and language modules, only the ones you imported will be bundled. @@ -10,13 +10,19 @@ import languageJavaScript from 'shiki/langs/js.mjs'; import languagePython from 'shiki/langs/py.mjs'; import languageTypeScript from 'shiki/langs/ts.mjs'; +function addjustTheme(theme: ThemeRegistrationRaw): ThemeRegistrationRaw { + return { + ...theme, + colors: { + ...theme.colors, + 'editor.background': `var(--webchat__code-block--background, ${theme.colors['editor.background']})` + } + }; +} + function createHighlighter() { return createHighlighterCore({ - themes: [ - // instead of strings, you need to pass the imported module - themeGitHubDark, - themeGitHubLight - ], + themes: [addjustTheme(themeGitHubDark), addjustTheme(themeGitHubLight)], langs: [languageJavaScript, languagePython, languageTypeScript], engine: createJavaScriptRegexEngine() }); diff --git a/packages/fluent-theme/src/components/theme/Theme.module.css b/packages/fluent-theme/src/components/theme/Theme.module.css index dffd36ea28..bd88b9edd4 100644 --- a/packages/fluent-theme/src/components/theme/Theme.module.css +++ b/packages/fluent-theme/src/components/theme/Theme.module.css @@ -2,7 +2,7 @@ /* biome-ignore format: do not print each class on the new line */ .a, .b, .c, .d, .e, .f, .g, .h, .i, .j, .k, .l, .m, .n, .o, .p, .q, .r, .s, .t, .v, .w, .u, .x, .y, .z, .A, .B, .C, .D, .E, .F, .G, .H, .I, .J, .K, .L, .M, .N, .O, .P, .Q, .R, .S, .T, .V, .W, .U, .X, .Y, .Z { - /* biome-ignore lint: esbuild considers empty global classes as used and removes them due to lack of rules */ + /* esbuild considers empty global classes as used and removes them due to lack of rules */ } } @@ -72,6 +72,10 @@ --webchat-colorGray190: var(--colorGray190, #201f1e); --webchat-colorGray200: var(--colorGray200, #1b1a19); + /* New greys from the link above not exposed by Fluent */ + --webchat-colorGrey8: #141414; + --webchat-colorGrey98: #fafafa; + /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/utils/shadows.ts */ --webchat-shadow2: var(--shadow2, 0 0 2px rgba(0, 0, 0, 12%), 0 1px 2px rgba(0, 0, 0, 14%)); --webchat-shadow4: var(--shadow4, 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.14)); @@ -115,6 +119,7 @@ 'Helvetica Neue', sans-serif ); + --webchat-fontFamilyMonospace: var(--fontFamilyMonospace, Consolas, 'Courier New', Courier, monospace); --webchat-fontFamilyNumeric: var( --fontFamilyNumeric, Bahnschrift, @@ -161,7 +166,7 @@ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/strokeWidths.ts */ --webchat-strokeWidthThin: var(--strokeWidthThin, 1px); - --webchat-strokeWidthThick: var(--strokeWidthThicker, 2px); + --webchat-strokeWidthThick: var(--strokeWidthThick, 2px); --webchat-strokeWidthThicker: var(--strokeWidthThicker, 3px); /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/durations.ts */ @@ -217,8 +222,9 @@ padding-inline-start: var(--webchat-spacingHorizontalMNudge); } -/* Transcript scrollable */ -:global(.webchat-fluent).theme :global(.webchat__basic-transcript .webchat__basic-transcript__scrollable) { +/* Scrollbars */ +:global(.webchat-fluent).theme :global(.webchat__basic-transcript .webchat__basic-transcript__scrollable), +:global(.webchat-fluent).theme :global(.webchat__view-code-dialog__code-body) { /* Edge uses -webkit-scrollbar if scrollbar-* is not set */ scrollbar-color: unset; scrollbar-width: unset; @@ -231,6 +237,10 @@ visibility: hidden; } + &::-webkit-scrollbar-corner { + background: transparent; + } + &:hover::-webkit-scrollbar { width: var(--webchat-spacingVerticalMNudge); } @@ -357,7 +367,7 @@ } /* TODO: align with original fluent modal styles in WebChat as they don't match v9 anymore */ - :global(.webchat__modal-dialog__close-button):focus:not(:active):hover { + :global(.webchat__modal-dialog__close-button):not(:active):hover { background-color: var(--webchat-colorNeutralBackground3); } @@ -378,6 +388,125 @@ } } +/* View Code dialog */ +:global(.webchat-fluent).theme :global(.webchat__modal-dialog.webchat__view-code-dialog) { + :global(.webchat__modal-dialog__close-button-layout) { + display: flex; + padding: var(--webchat-spacingVerticalS) var(--webchat-spacingHorizontalS); + } + + :global(.webchat__modal-dialog__close-button) { + align-items: center; + aspect-ratio: 1; + display: flex; + height: var(--webchat-lineHeightBase300); + justify-content: center; + padding: 0; + width: unset; + } + + :global(.webchat__view-code-dialog__copy-button) { + background: transparent; + border: none; + color: var(--webchat-colorNeutralForeground1); + height: 20px; + margin-block-start: var(--webchat-spacingVerticalS); + padding: 0; + position: absolute; + right: 32px; + top: 0; + transition: background-color var(--webchat-durationNormal) var(--webchat-curveDecelerateMid); + width: 20px; + + :global(.webchat__code-block-copy-button__icon) { + background-color: currentColor; + } + + &:hover { + background: var(--webchat-colorNeutralBackground3); + } + + &:active { + background: var(--webchat-colorNeutralBackground3); + } + + &:focus { + outline-color: var(--webchat-colorStrokeFocus2); + } + } + + :global(.webchat__modal-dialog__box) { + width: fit-content; + } + + :global(.webchat__modal-dialog__body) { + margin: 0; + padding: var(--webchat-spacingVerticalS) var(--webchat-spacingHorizontalM); + } + + :global(.webchat__view-code-dialog__title) { + font-size: var(--webchat-fontSizeBase300); + font-weight: var(--webchat-fontWeightSemibold); + line-height: var(--webchat-lineHeightBase300); + } + + :global(.webchat__view-code-dialog__body) { + display: contents; + } + + :global(.webchat__view-code-dialog__code-body) { + background: var(--webchat__code-block--background); + font-family: var(--webchat-fontFamilyMonospace); + font-size: var(--webchat-fontSizeBase300); + line-height: var(--webchat-fontSizeBase300); + margin-inline: calc(var(--webchat-spacingHorizontalM) * -1); + padding-inline: var(--webchat-spacingHorizontalM); + } + + :global(.webchat__view-code-dialog__code-body:has(.shiki:focus-visible)):focus-within { + outline: var(--webchat-strokeWidthThick) solid var(--webchat-colorStrokeFocus2); + outline-offset: calc(var(--webchat-strokeWidthThick) * -1); + + :global(.shiki) { + outline: none; + } + } + + :global(.webchat__view-code-dialog__code-body:has(.shiki.github-light-default)) { + --webchat__code-block--background: var(--codeBlockBackground, var(--webchat-colorGrey98)); + } + + :global(.webchat__view-code-dialog__code-body:has(.shiki.github-dark-default)) { + --webchat__code-block--background: var(--codeBlockBackground, var(--webchat-colorGrey8)); + } + + :global(.webchat__view-code-dialog__footer) { + color: var(--webchat-colorNeutralForeground4); + font-size: var(--webchat-fontSizeBase100); + line-height: var(--webchat-lineHeightBase100); + } + + :global(.webchat__view-code-dialog__link) { + color: var(--webchat-colorBrandForegroundLink); + text-decoration-color: transparent; + + &:target { + color: var(--webchat-colorBrandForegroundLinkSelected); + } + &:hover { + color: var(--webchat-colorBrandForegroundLinkHover); + text-decoration: underline 1px currentColor; + } + &:active { + color: var(--webchat-colorBrandForegroundLinkPressed); + } + &:focus-visible { + outline: none; + text-decoration: underline 1px double var(--webchat-colorStrokeFocus2); + } + } +} + /* Activity button */ :global(.webchat-fluent).theme :global(.webchat__activity-button) { background: var(--webchat-colorNeutralBackground1);