AdaptiveCards
AdaptiveCards copied to clipboard
[AC New Features] Static Header for Carousel
Description
The horizontal carousel currently does not support a way for users to add a header to their carousel that remains static even after paginating through the carousel. A use case for this would be a card author wanting to use the carousel to display related content on different pages of the carousel. Instead of the same title paginating with the content in the carousel, we should enable something like this:

In this example one case observe that the carousel header remains in a fixed position while the carousel content (in this case only images, but could be any supported carousel element) paginates.
Describe the solution you'd like
| Capability | Priority |
|---|---|
| Allow text to remain static above carousel content serving as a static carousel header | Must |
| Support multiple lines in header | Must |
| When a header is used with a carousel the carousel arrows need to be vertically centered with the carousel content (the content that is paginating) and not the whole container | Must |
| The user must be able to add some spacing between the header and the carousel content | Must |
| Ability to style header text on a per line basis (size, weight, isSubtle, accent) | Should |
Implementation Platforms
- [X] JS
- [ ] .NET WPF
- [ ] Android
- [ ] iOS
- [ ] UWP
Per Line Text Style
Supporting different text styling such as different fonts per line of text is not a must for this feature but we have to consider it as customers may request for it in the future.

In order to make the current implementation future proof such that it won't require us investing in this area repeatedly, there are four options we can consider.
option 1: Use TextBlock and defer implementing line specific styling until it's asked as it's not required.
option 2a: Use RichTextBlock, and add style option to RichTextBlock's TextRun as we did for TextBlock.
option 2b: Use RichTextBlock, and have Carousel renderer to set header a11y role to the inlines.
option 3: Use Container and leave it to Card author to update a11y role header using TextBlock.
Example of proposed new schema of 2a
"header":
{
"type": "RichTextBlock",
"inlines": [
"This is the first inline. ",
{
"type": "TextRun",
"text": "We support colors,",
"color": "good",
"style": "header"
}
]
}
option 1:
pro:
Easy to implement and ready to ship.
cons:
Could force users to change their old payload.
option 2a:
pro:
Meets all of the requirement and fairly easy to implement
con:
Must implement for all of the renders at some point; verification and publishing patches for them
option 2b:
pro:
Same pro of option2a + doesn't have to implement for all of the renderers since a11y role is implemented at the carousel renderer.
cons:
All of TextRuns in RichTextBlock get the a11y header role; there isn't way to designate a specific TextRun to be a a11y header.
option 3:
pro:
Gives the author the most options to implement their design vision
con:
We have to clearly communicate that Container has to be a parent element to users.
Can be cumbersome to use if user just wants to have a simple text based header.
Issues of enforcing forbidden items. Should we enforce the same policy of Carousel to it?
Will the policy diverge in the future, and if so, how do we keep track and maintain it?
Spacing
This feature applies to spacing between header and carousel.
option 1
Have users to specify spacing by using new line characters such as '\n' and '\r'.
option 2
Make use of spacing property in Carousel
I'm in favor of option 1 or b1. Let's verify with PMs if the different styles for each line is a requirement. I believe that even if it's not required now, it will be so it's better if we go with b1 and be ahead with the implementation. "Must implement for all of the renders at some point" - is it's just for the carousel? the carousel is not implemented in other renderers anyways (or is it?....), so can we refactor/add the title when we'll implement the carousel for other renderers? regardless, i believe that there's no urgency there as the title ask is for the JS renderer only at this point.
Spacing - is the use of "\n" and "\r" common and valid for all cases when the user needs multiple lines? if yes then option 1 is probably ok. otherwise we should probably go with option 2
Per Line Text Style
Supporting different text styling such as different fonts per line of text is not a must for this feature but we have to consider it as customers may request for it in the future.
In order to make the current implementation future proof such that it won't require us investing in this area repeatedly, there are four options we can consider.
option 1: Use TextBlock and defer implementing line specific styling until it's asked as it's not required. option 2a: Use RichTextBlock, and add
styleoption to RichTextBlock's TextRun as we did for TextBlock. option 2b: Use RichTextBlock, and have Carousel renderer to set header a11y role to the inlines. option 3: Use Container and leave it to Card author to update a11y role header using TextBlock.Example of proposed new schema of 2a
"header": { "type": "RichTextBlock", "inlines": [ "This is the first inline. ", { "type": "TextRun", "text": "We support colors,", "color": "good", "style": "header" } ] }option 1:
pro:
Easy to implement and ready to ship.
cons:
Could force users to change their old payload.
option 2a:
pro:
Meets all of the requirement and fairly easy to implement
con:
Must implement for all of the renders at some point; verification and publishing patches for them
option 2b:
pro:
Same pro of option2a + doesn't have to implement for all of the renderers since a11y role is implemented at the carousel renderer.
cons:
All of TextRuns in RichTextBlock get the a11y header role; there isn't way to designate a specific TextRun to be a a11y header.
option 3:
pro:
Gives the author the most options to implement their design vision
con:
We have to clearly communicate that
Containerhas to be a parent element to users. Can be cumbersome to use if user just wants to have a simple text based header. Issues of enforcing forbidden items. Should we enforce the same policy of Carousel to it? Will the policy diverge in the future, and if so, how do we keep track and maintain it?Spacing
This feature applies to spacing between header and carousel.
option 1
Have users to specify spacing by using new line characters such as '\n' and '\r'.
option 2
Make use of spacing property in Carousel
Thank you for creating the proposal. For this specific feature I believe we should:
- Make as little schema changes as possible
- Build in a future proof way that saves our team from having to make changes to this in the future and potentially introducing breaking changes
I don't think we should go with an approach that will cause the a11y team to file a bug on us in the future.
If we were to choose option 1 and only allow TextBlock, would a user creating a header with multiple lines be able to specify a specific line in the TextBlock to apply the a11y header role to or would it be applied to the entire TextBlock? If it is applied to the entire TextBlock, then I think it is the same experience as the a11y header role getting applied to all of the TextRuns in RichTextBlock. Ultimately, the a11y header role is only an issue if the user has multiple lines of text in the header and they only want this on a specific line. If this is not possible with TextBlock, then I think we should go with option 2b as the con listed in 2b would also apply to option 1.
On the subject of spacing I mainly want to make sure that the spacing property on the Carousel is respected and capable of pushing the Carousel content down if the user desires this.
For example, let's assume the following screenshot has set the spacing property on the Carousel element to "small".

The expectation for this request is that if the user sets spacing to be "large" in the previous example the Carousel content would move down more giving more space to the header. On the other hand if the user specifies spacing to be "none" then the Carousel would appear closer to the header. I believe this is already implemented as it works for every other container/element we have, but wanted to make sure it was called out just in case the Carousel worked differently.
Can you create a PR for this? It's hard to track in issue and add comments. (Easy to be lost) I prefer header as just a container:
- we may need to support footer someday. which may add like button and other stuff
- we may add icon, http link or other things to header.
@KesemZ Option 2a updates RichTextBlock to have style option that TextBlock currently has. If we does that, then we need to update all of the renderers, iOS, Android and etc to be consistent.
@KesemZ & @JeanRoca for 2b, I will check with a11y people if assigning header role to the entire RichTextBlock is o.k. For spacing, I will go with option 2 since there are no strong objections to it, and it follows the current CardElement's spacing behavior.
@licanhua I agree with you on the most of the points. what about the cons listed under option 3? RichTextBlock supports select actions that supports Action.OpenUrl.
@all I've created PR. If you prefer, we can discuss further from there.
@jwoo-msft - with the answer we got from the accessibility team, sounds like the best implementation is to have 3 seperate headers (with 3 separate descriptions and styles) - it could be header Title sub-title
Will it make sense to implement it this way?
Please continue the discussion on the PR. I moved all comments to https://github.com/microsoft/AdaptiveCards/pull/7751