Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Legends:

## [Unreleased]

### Added

- Added `styleOptions.richCardTitleAsHeading` (default `true`) to control whether hero/thumbnail/audio/video/animation/receipt card titles render with Adaptive Cards `style: 'heading'` (and the resulting `role="heading"` + `aria-level`). Hosts whose card titles do not represent navigational headings (e.g. cards inside a chat transcript) can opt out by setting it to `false`, reconciling the contradiction between the original [#4327](https://github.com/microsoft/BotFramework-WebChat/issues/4327) (add the heading) and downstream a11y audits that flag it as unnecessary.

### Changed

- Removed `markdown-it` and completed migration to `micromark`, in PR [#5825](https://github.com/microsoft/BotFramework-WebChat/pull/5825), by [@compulim](https://github.com/compulim)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<main id="webchat"></main>
<script>
run(async function () {
const store = testHelpers.createStore();
const directLine = WebChat.createDirectLine({ token: await testHelpers.token.fetchDirectLineToken() });
const styleOptions = { richCardTitleAsHeading: false };
const baseProps = { directLine, store, styleOptions };
const webChatElement = document.getElementById('webchat');

WebChat.renderWebChat(baseProps, webChatElement);

await pageConditions.uiConnected();

await pageObjects.sendMessageViaSendBox('herocard', { waitForSend: true });
await pageConditions.minNumActivitiesShown(2);
await pageConditions.scrollToBottomCompleted();

// The hero card title text block should be present...
const titleTextBlock = document.querySelector('.ac-textBlock');
expect(titleTextBlock).toHaveProperty('innerText', '\u200BDetails about image 1\u200B');

// ...but it must not be a programmatic heading when richCardTitleAsHeading is false.
expect(document.querySelector('.ac-textBlock[role="heading"]')).toBe(null);
Comment thread
cjennison marked this conversation as resolved.
Outdated
});
</script>
</body>
</html>
15 changes: 15 additions & 0 deletions packages/bundle/src/adaptiveCards/AdaptiveCardsStyleOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ type StrictAdaptiveCardsStyleOptions = {
* Enable title (and subtitle) wrapping
*/
richCardWrapTitle: boolean | undefined;

/**
* Cards: Rich Cards
*
* When `true` (default, preserves historical behavior), the title of a hero/thumbnail/audio/video/
* animation/receipt card is rendered with Adaptive Cards `style: 'heading'`, which the Adaptive
* Cards SDK exposes via `role="heading"` + `aria-level`.
*
* Set to `false` when these card titles are not navigational headings in your host page
* (e.g. when card titles appear inside a chat transcript and would create misleading
* heading structure for assistive technology). See:
* - Original request to add the heading: https://github.com/microsoft/BotFramework-WebChat/issues/4327
* - Reverse request to make it removable: (the audit motivating this option)
*/
richCardTitleAsHeading: boolean | undefined;
Comment thread
cjennison marked this conversation as resolved.
Outdated
};

type AdaptiveCardsStyleOptions = Partial<StrictAdaptiveCardsStyleOptions>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,15 @@ export default class AdaptiveCardBuilder {
}

addCommonHeaders(content: ICommonContent) {
const { richCardWrapTitle } = this.styleOptions;
const { richCardTitleAsHeading, richCardWrapTitle } = this.styleOptions;
// Default to `true` to preserve historical behavior (see github.com/microsoft/BotFramework-WebChat/issues/4327).
Comment thread
cjennison marked this conversation as resolved.
Outdated
// Hosts whose card titles do not represent navigational headings (e.g. when cards appear inside a chat
// transcript) should set `styleOptions.richCardTitleAsHeading` to `false` to drop the `style: 'heading'`
// and avoid an unnecessary `role="heading"` / `aria-level` on the title.
this.addTextBlock(content.title, {
color: TextColor.Default,
size: TextSize.Medium,
style: 'heading',
...(richCardTitleAsHeading === false ? {} : { style: 'heading' as const }),
weight: TextWeight.Bolder,
wrap: richCardWrapTitle
});
Expand Down
1 change: 1 addition & 0 deletions packages/bundle/src/adaptiveCards/defaultStyleOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const ADAPTIVE_CARDS_DEFAULT_STYLE_OPTIONS: Required<AdaptiveCardsStyleOptions>
cardEmphasisBackgroundColor: '#F9F9F9',
cardPushButtonBackgroundColor: '#0063B1',
cardPushButtonTextColor: 'White',
richCardTitleAsHeading: true,
richCardWrapTitle: false
};

Expand Down