Repository navigation
Ensure 4.5:1 contrast for syntax-highlighted code and keep code blocks when messages are already in the store - #5893
Conversation
|
TODO: dark variant verification for both light and dark codeblock themes |
|
William Wong (compulim)
left a comment
There was a problem hiding this comment.
I don't know where these strings are, but they are in the screenshots.
Typescript -> TypeScript
Javascript -> JavaScript
Comments of github-light-default (#6e7781) are 4.36:1 on the #fafafa code block background of the Fluent theme. Token colors below 4.5:1 against the Fluent code block backgrounds are now mixed with black or white, keeping their hue, through Shiki's colorReplacements. The "View code" step of side-by-side is checked again in the light theme; its dark theme still fails for the FAQ link.
ShikiComposer has no highlighter until Shiki loads. Activities already in the store render before that, CodeHighlighterComposer called an undefined highlighter and threw in its error handler, and the code block stayed empty. Without a highlighter, CodeHighlighterComposer now uses the upstream one. createDirectLineEmulator subscribed with an async function, whose promise was called as a teardown function when Web Chat unmounted.
Also describe the remount fix as rendering with messages already in the store, which includes a new store created from a saved state.
Add contrast.fluent.dark.html and contrast.code-block-dark.fluent.dark.html: the Fluent theme in a FluentProvider with webDarkTheme, with the light and the dark code block theme. The code block theme is a style option and does not follow the color scheme, so both combinations are reachable.
…ing every color Instead of computing replacements for every token color below 4.5:1 at runtime (ensureContrast), the light code block theme now replaces only the color that fails: comments in github-light-default (#6e7781) are 4.36:1 on the Fluent theme code block background (#fafafa). They now use the muted text color of the same theme, #656d76 (GitHub Primer fg.muted): 5.03:1 on #fafafa and 5.25:1 on #ffffff. Every other color of JavaScript, Python, and TypeScript tokens is at least 4.83:1 (light theme, #8250df on #fafafa) and 5.99:1 (dark theme, #8b949e on #141414), so the dark theme is unchanged.
05d288c to
8bd71d9
Compare
|
William Wong (@compulim) the language comes from payload in lowercase string and we capitalize the first letter via CSS, if I recall correctly. |
|
William Wong (@compulim) thanks for unblocking the PR and I'll make a follow-up mapping name to language title. We can make it localizable too. |
Changelog Entry
Fixed
github-light-default) were 4.36:1 in the Fluent theme and now use the muted text color of the theme,#656d76(5.03:1), in PR #5893, by @OEvgenyDescription
Web Chat paints the code block background itself. The Fluent theme uses
#fafafa(light) and#141414(dark). The GitHub code themes were designed for#ffffffand#0d1117. On#fafafa, comments ofgithub-light-default(#6e7781) are 4.36:1 by the WCAG formula, which axe rounds down to 4.35:1. The "View code" dialog ofside-by-side/codeblock.navigation.htmlhit this, so that check was skipped.The light code block theme passed to Shiki now replaces the comment color with
colorReplacements: { '#6e7781': '#656d76' }.#656d76is the muted text color of the same theme (GitHub Primer'sfg.muted), with about the same hue: 5.03:1 on#fafafaand 5.25:1 on#ffffff. The dark code block theme is unchanged.The same Shiki integration also left code blocks empty when Web Chat was rendered with messages already in the store: rendered again with the same store, or with a store created from a saved state. These messages rendered before the new highlighter had loaded.
CodeHighlighterComposerthen called anundefinedhighlighter, and its error handler threw onhighlightCode.name. The code block had already moved its code out, so it stayed empty. While no highlighter is set,CodeHighlighterComposernow uses the one above it, which is the plain-text highlighter by default.Design
colorReplacementson the theme. Only comments fail: every other foreground of the two themes that JavaScript, Python, and TypeScript tokens use is at least 4.83:1 in the light theme (#8250dfon#fafafa) and 5.99:1 in the dark theme (#8b949eon#141414). The other rules below 4.5:1 have background-like foregrounds (markup.ignored,markup.untracked,carriage-return), which the bundled grammars do not produce. A Shiki update with new theme colors, or a new language, could bring a failing color; the accessibility check in the new tests catches it for the sampled tokens.#656d76is the color the theme itself uses for muted text, so comments stay in its palette. It is checked against the Fluent background, which is darker than the default theme's#ffffff. It also leaves a margin for hosts that set--codeBlockBackgroundto a slightly darker gray, such as Fluent'scolorNeutralBackground3#f5f5f5(4.81:1). Hosts are responsible for the contrast of their own background, as before.#656d76for comments. It already passed at 4.55:1, but there is one highlighter for both themes. Existing snapshots are unchanged: the difference is under the image snapshot threshold. The accessibility check in the new tests catches a regression.pointer-events: none) cover it, and axe reports it as "incomplete" instead of failing.codeBlockThemestyle option and does not follow the color scheme, and the code block background does not follow the Fluent UI theme. So a dark Web Chat can show either code block theme on the same backgrounds as a light one. Verified combinations (lowest token contrast, measured in the transcript and in the "View code" dialog):#ffffff): 5.05:1 (#8250df; comments 5.25:1). Dark code theme (#0d1117): 6.15:1. The default theme has no dark variant, andprefers-color-scheme: darkdoes not change either background.#fafafa) 4.83:1 (#8250df; comments 5.03:1), dark code theme (#141414) 5.99:1.webDarkTheme): light code theme 4.83:1, dark code theme 5.99:1. The same in the Copilot variant and with a custom brand ramp.markdown/vnext/markdownStreaming.htmlkeeps its skips: without them, it fails only for the level-one heading ([Programmatic Access - BOT Framework - Web Chat > Enter Keyword]: Multiple H1 headings are defined for the controls like 'Accessibility', 'Adaptive card', 'Animation card' and etc. #4721), not for color contrast.Follow-ups, not in this PR:
side-by-sidepages, the FAQ link in the "View code" dialog is 2.81:1 (#5661d4, the test palette'sbrand[100], on#292929). The skip is now limited to the dark theme.Specific Changes
bundle/src/codeHighlighter/shiki.ts: the light code block theme (github-light-default) replaces the comment color#6e7781with#656d76component/.../createCodeHighlighterComposer.tsx:highlightCodeis optional. Without it, the upstream highlighter is usedtest/page-object/.../createDirectLineEmulator.js: the subscribe function is no longerasync. Its promise was called as a teardown function when Web Chat unmounted, which loggedTypeError: n is not a functionAdded
__tests__/html2/markdown/codeBlock/contrast.html(default and Fluent themes, light and dark code themes, and the Fluent theme in a dark Fluent UI theme with either code theme): opens the "View code" dialog for JavaScript, TypeScript, and Python with comments, strings, keywords, and other tokens, with the default accessibility check. Fails onmainin the Fluent theme, light and dark:insufficient color contrast of 4.35 (foreground color: #6e7781, background color: #fafafa)Added
__tests__/html2/markdown/codeBlock/remount.html: renders Web Chat again with the same store and expects the Python code block to be highlighted. Fails onmainwith the code block empty andTypeError: Cannot read properties of undefined (reading 'name')__tests__/html2/side-by-side/index.html: the "View code" dialog step is checked again in the light theme, and the TODO now only mentions the FAQ link in the dark themeI have added tests and executed them locally
I have updated
CHANGELOG.mdI have updated documentation
Review Checklist
z-index)package.jsonandpackage-lock.jsonreviewed