I'm trying to use CSS to style the adaptive cards on a more fine grained level, however the similar names of the default CSS classes makes it difficult to target individual elements.
I've attempted to try target it with specific parameters, but they still end up crossing rules to some extent. I've tried using unique ids or uniqueCSSSelectors during the adaptive card build process, but it seems they are all stripped out by the time it makes it to the front end.
Here are some examples of what I've tried so far.
li div .content .attachment .attachment div .ac-container:not(:first-child) .ac-columnSet:hover{
background: #e6eaed;
color: #323232;
}
li div .content .attachment .attachment div .ac-container:not(:first-child) .ac-columnSet:hover .ac-container .ac-textBlock p{
color: #323232;
}```
First, I want to mention that this ability is already a feature request that is being worked on in the BotFramework-WebChat repo. I don't know the ETA on this, so don't plan on it being soon. But, do keep an eye out.
This is doable with a little hacking. In short, these are your steps:
activityMiddleware
that looks for the trigger value. When received, then update the element that will hold the incoming adaptive card by attaching an id
.id
in step 2.activityMiddleware
object to direct line.Hope of help!
Here's example code:
mainDialog.js - Adaptive card to be sent from my bot
async basicAdaptiveCard ( stepContext ) {
const card = {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"trigger": "ServiceCardTrigger",
"body": [
{
"type": "TextBlock",
"text": "Hi!! How can I help you today?",
"weight": "Bolder",
"size": "Medium"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Placeholder Message",
"data": "close"
}
]
}
const ac_card = CardFactory.adaptiveCard( card );
await stepContext.context.sendActivity(
{
attachments: [ ac_card ]
}
);
return { status: DialogTurnStatus.waiting };
}
index.html - Showing only the essential bits. In this I'm tracking via a button with the value that includes "Service details". It's simplistic, but works for the demo. Update as necessary.
<style>
#ServiceCard {
background-color: #e6eaed;
color: #323232;
}
#ServiceCard:hover p {
color: red
}
</style>
[...]
<script type="text/babel">
[...]
const activityMiddleware = () => next => card => {
const { activity: { from, type, attachments } } = card;
if (type === 'message' && from.role === 'bot') {
if(attachments && attachments[0].content.trigger === 'ServiceCardTrigger') {
let children = document.getElementsByClassName('ac-adaptiveCard');
for (let i = 0, j = children.length; i <= j; i++) {
if(i === j - 1) {
let child = children[i];
if(child.lastChild.innerHTML.includes('Service details')) {
child.id = 'ServiceCard';
}
}
};
}
}
else {
return next(card)
}
}
[...]
window.ReactDOM.render(
<ReactWebChat
activityMiddleware={ activityMiddleware }
directLine={ directLine }
username={'johndoe'}
/>,
document.getElementById( 'webchat' )
);
[...]
</script>