Skip to content

Commit 45caa27

Browse files
authored
[Designer] Update container styling to fix overflow and sizing (#7899)
* Switch padding to margin and update card heights * Adjust width and height for border * Switch header to use margins * Update widget container styling * Remove border when background image is present and move logic to widget container class (#8022) * Remove host container logic from card designer surface
1 parent 62dd146 commit 45caa27

File tree

6 files changed

+186
-33
lines changed

6 files changed

+186
-33
lines changed

source/nodejs/adaptivecards-designer/src/card-designer-surface.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as ACData from "adaptivecards-templating";
1010
import * as Shared from "./shared";
1111
import { HostContainer } from "./containers";
1212
import { FieldDefinition } from "./data";
13+
import { Strings } from "./strings";
1314

1415
export enum BindingPreviewMode {
1516
NoPreview,
@@ -387,19 +388,33 @@ export class CardDesignerSurface {
387388

388389
let renderedCard = cardToRender.render();
389390

391+
if (this._cardHost.innerHTML === "") {
392+
this._cardHost.appendChild(renderedCard);
393+
}
394+
390395
if (this.fixedHeightCard) {
391-
renderedCard.style.height = "100%";
392-
393396
// truncate the content if the host container is fixed height
394-
if (this.isPreviewMode)
395-
{
396-
renderedCard.style.overflow = "hidden";
397+
if (this.isPreviewMode) {
398+
if (this.context.hostContainer?.requiresOverflowStyling()) {
399+
this.appendErrorMessage(Strings.widgetOverflowWarning);
400+
} else {
401+
renderedCard.style.overflow = "hidden";
402+
}
397403
}
404+
this.context.hostContainer?.adjustStyleForBackground();
405+
renderedCard.style.height = "100%";
398406
}
407+
}
399408

400-
if (this._cardHost.innerHTML === "") {
401-
this._cardHost.appendChild(renderedCard);
402-
}
409+
private appendErrorMessage(message: string) {
410+
let errorElement = document.createElement("div");
411+
errorElement.className = "acd-error-pane-message";
412+
413+
errorElement.innerText = message;
414+
errorElement.style.whiteSpace = "normal";
415+
416+
const errorPane = document.getElementById("errorPane");
417+
errorPane.appendChild(errorElement);
403418
}
404419

405420
private addPeer(peer: DesignerPeers.DesignerPeer, insertAfterNeighbor: boolean = false) {

source/nodejs/adaptivecards-designer/src/containers/host-container.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ export abstract class HostContainer {
6060
return new HostConfig(hostConfig);
6161
}
6262

63+
public requiresOverflowStyling(): boolean {
64+
// By default, overflow styling is not handled
65+
return false;
66+
}
67+
68+
public adjustStyleForBackground(): void {
69+
// By default, we make no adjustments
70+
return;
71+
}
72+
6373
supportsActionBar: boolean = false;
6474

6575
get cardHost(): HTMLElement {

source/nodejs/adaptivecards-designer/src/containers/widget/widget-container-dark.css

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,55 @@
11
.widget-outer-container {
22
border: 1px solid rgba(0, 0, 0, 0.1);
33
background: #2c2c2c;
4-
width: 300px;
4+
width: 302px;
55
border-radius: 8px;
66
box-sizing: border-box;
77
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08);
88
position: relative;
99
}
1010

1111
.widget-header {
12-
height: 48px;
13-
width: 298px;
12+
height: 16px;
13+
width: 268px;
1414
position: absolute;
1515
z-index: 1;
1616
display: flex;
1717
justify-content: space-around;
18-
padding: 16px;
18+
margin: 16px;
1919
border-radius: 8px 8px 0px 0px;
2020
}
2121

2222
.widget-large-container {
23-
height: 462px;
23+
height: 464px;
2424
}
2525

2626
.widget-medium-container {
27-
height: 304px;
27+
height: 306px;
2828
}
2929

3030
.widget-small-container {
31-
height: 146px;
31+
height: 148px;
32+
}
33+
34+
.widget-large-container-no-border {
35+
height: 462px !important;
36+
border: 0px !important;
37+
}
38+
39+
.widget-medium-container-no-border {
40+
height: 304px !important;
41+
border: 0px !important;
3242
}
3343

44+
.widget-small-container-no-border {
45+
height: 146px !important;
46+
border: 0px !important;
47+
}
3448

3549
/* widget-large/medium/small-container 4px(top+bottom padding+margin) widget-outer-container border*/
3650

3751
.widget-large-card {
38-
height: 462px;
52+
height: 462px
3953
}
4054

4155
.widget-medium-card {
@@ -49,7 +63,18 @@
4963
.ac-adaptiveCard {
5064
border: 0px;
5165
padding: 48px 16px 16px 16px !important;
52-
border-radius: 8px !important;
66+
margin: 0px !important;
67+
border-radius: 8px;
68+
}
69+
70+
.ac-card-elements-wrapper {
71+
height: 100%;
72+
margin: 0px -16px 0px -16px !important;
73+
padding: 0px 16px 0px 16px !important;
74+
}
75+
76+
.no-overflow {
77+
overflow: hidden;
5378
}
5479

5580
.ac-input {

source/nodejs/adaptivecards-designer/src/containers/widget/widget-container-light.css

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,67 @@
11
.ac-adaptiveCard {
22
border: 0px;
33
padding: 48px 16px 16px 16px !important;
4-
border-radius: 8px !important;
4+
margin: 0px !important;
5+
border-radius: 8px;
6+
}
7+
8+
.ac-card-elements-wrapper {
9+
height: 100%;
10+
margin: 0px -16px 0px -16px !important;
11+
padding: 0px 16px 0px 16px !important;
12+
}
13+
14+
.no-overflow {
15+
overflow: hidden;
516
}
617

718
.widget-outer-container {
819
border: 1px solid rgba(0, 0, 0, 0.0578);
920
background: #f6f6f6;
10-
width: 300px;
21+
width: 302px;
1122
border-radius: 8px;
1223
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.065);
1324
box-sizing: border-box;
1425
position: relative;
1526
}
1627

1728
.widget-header {
18-
height: 48px;
19-
width: 298px;
29+
height: 16px;
30+
width: 268px;
2031
position: absolute;
2132
z-index: 1;
2233
display: flex;
2334
justify-content: space-around;
24-
padding: 16px;
35+
margin: 16px;
2536
border-radius: 8px 8px 0px 0px;
2637
}
2738

2839
.widget-large-container {
29-
height: 462px;
40+
height: 464px;
3041
}
3142

3243
.widget-medium-container {
33-
height: 304px;
44+
height: 306px;
3445
}
3546

3647
.widget-small-container {
37-
height: 146px;
48+
height: 148px;
49+
}
50+
51+
.widget-large-container-no-border {
52+
height: 462px !important;
53+
border: 0px !important;
3854
}
3955

56+
.widget-medium-container-no-border {
57+
height: 304px !important;
58+
border: 0px !important;
59+
}
60+
61+
.widget-small-container-no-border {
62+
height: 146px !important;
63+
border: 0px !important;
64+
}
4065

4166
/* widget-large/medium/small-container 4px(top+bottom padding+margin) widget-outer-container border*/
4267

@@ -307,11 +332,11 @@ a.ac-anchor:hover {
307332
}
308333

309334
.ac-carousel-container {
310-
padding: 0px 16px 16px 16px !important;
335+
padding: 0px 16px 16px 16px !important;
311336
}
312337

313338
.ac-carousel-card-level-container {
314-
margin: 0px -16px -16px -16px !important;
339+
margin: 0px -16px -16px -16px !important;
315340
}
316341

317342
.ac-container.ac-adaptiveCard .swiper-button-prev.ac-carousel-left,

source/nodejs/adaptivecards-designer/src/containers/widget/widget-container.ts

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export enum ContainerSize {
1313

1414
export class WidgetContainer extends MultiThemeHostContainer {
1515
private _containerSize: ContainerSize;
16+
private _outerFrame: HTMLDivElement;
1617

1718
constructor(size: ContainerSize) {
1819
super(
@@ -25,6 +26,8 @@ export class WidgetContainer extends MultiThemeHostContainer {
2526
);
2627
this._containerSize = size;
2728
}
29+
30+
static readonly widgetPadding: number = 16;
2831

2932
public initialize(): void {
3033
super.initialize();
@@ -38,13 +41,13 @@ export class WidgetContainer extends MultiThemeHostContainer {
3841
"widget-large-card"
3942
);
4043
this.cardHost.classList.add(`widget-${this._containerSize.toLowerCase()}-card`);
41-
const outerFrame = document.createElement("div");
42-
outerFrame.classList.add("widget-outer-container");
43-
outerFrame.classList.add(`widget-${this._containerSize.toLowerCase()}-container`);
44+
this._outerFrame = document.createElement("div");
45+
this._outerFrame.classList.add("widget-outer-container");
46+
this._outerFrame.classList.add(`widget-${this._containerSize.toLowerCase()}-container`);
4447

4548
const header = document.createElement("div");
4649
header.className = "widget-header";
47-
outerFrame.appendChild(header);
50+
this._outerFrame.appendChild(header);
4851

4952
const headerText = document.createElement("p");
5053
headerText.className = "widget-header-text";
@@ -61,8 +64,80 @@ export class WidgetContainer extends MultiThemeHostContainer {
6164
innerFrame.className = "widget-inner-container";
6265
innerFrame.appendChild(this.cardHost);
6366

64-
outerFrame.appendChild(innerFrame);
65-
hostElement.appendChild(outerFrame);
67+
this._outerFrame.appendChild(innerFrame);
68+
hostElement.appendChild(this._outerFrame);
69+
}
70+
71+
public requiresOverflowStyling(): boolean {
72+
const renderedCard = document.getElementsByClassName("ac-adaptiveCard")[0] as HTMLElement;
73+
74+
const cardHeight = renderedCard.getBoundingClientRect().height;
75+
const widgetHeight = this.cardHost.getBoundingClientRect().height;
76+
77+
if (cardHeight > widgetHeight) {
78+
this.applyWidgetOverflowStyling(renderedCard);
79+
return true;
80+
}
81+
return false;
82+
}
83+
84+
private applyWidgetOverflowStyling(renderedCard: HTMLElement) {
85+
renderedCard.style.height = "100%";
86+
87+
const cardElementsWrapper = this.addCardElementsWrapper(renderedCard);
88+
cardElementsWrapper.classList.add("no-overflow");
89+
90+
const carouselElements = renderedCard.getElementsByClassName("ac-carousel-container");
91+
92+
for (let i = 0; i < carouselElements.length; i++) {
93+
const currentCarousel = carouselElements[i] as HTMLElement;
94+
95+
const carouselRect = currentCarousel.getBoundingClientRect();
96+
const wrapperRect = cardElementsWrapper.getBoundingClientRect();
97+
98+
// pagination will be in the bottom 16px of a carousel
99+
const paginationTop = carouselRect.bottom - 16;
100+
const paginationBottom = carouselRect.bottom;
101+
102+
const paginationOverlapsBoundary = ((paginationBottom >= wrapperRect.bottom) && (paginationBottom < (wrapperRect.bottom + WidgetContainer.widgetPadding)) ||
103+
(paginationTop >= wrapperRect.bottom) && (paginationTop < (wrapperRect.bottom + WidgetContainer.widgetPadding)));
104+
105+
if (paginationOverlapsBoundary) {
106+
// Hide overflow on the cardElement instead of the wrapper since pagination dots are in the margin
107+
renderedCard.classList.add("no-overflow");
108+
cardElementsWrapper.classList.remove("no-overflow");
109+
110+
// Add the padding to the carousel if the pagination dots are in the margin
111+
currentCarousel.style.marginBottom = WidgetContainer.widgetPadding + "px";
112+
break;
113+
}
114+
}
115+
}
116+
117+
private addCardElementsWrapper(parentElement: Element): HTMLElement {
118+
const cardElementsWrapper = document.createElement("div");
119+
cardElementsWrapper.classList.add("ac-card-elements-wrapper");
120+
121+
Array.from(parentElement.children).forEach((child) => {
122+
cardElementsWrapper.appendChild(child);
123+
})
124+
125+
parentElement.appendChild(cardElementsWrapper);
126+
return cardElementsWrapper;
127+
}
128+
129+
public adjustStyleForBackground() {
130+
this._outerFrame.classList.remove(
131+
"widget-small-container-no-border",
132+
"widget-medium-container-no-border",
133+
"widget-large-container-no-border"
134+
);
135+
136+
const renderedCard = document.getElementsByClassName("ac-adaptiveCard")[0] as HTMLElement;
137+
if (renderedCard.style.backgroundImage) {
138+
// If there is a background image present, we should remove the border
139+
this._outerFrame.classList.add(`widget-${this._containerSize.toLowerCase()}-container-no-border`);
140+
}
66141
}
67142

68143
get targetVersion(): Adaptive.Version {

source/nodejs/adaptivecards-designer/src/strings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { WidgetContainer } from "./containers";
2+
13
export class Strings {
24
static readonly toolboxes = {
35
toolPalette: {
@@ -29,4 +31,5 @@ export class Strings {
2931
}
3032
};
3133
static loadingEditor = "Loading editor...";
34+
static readonly widgetOverflowWarning = `[Designer] We have adjusted your card to hide overflow elements. Please ensure all card elements are contained within the proper card height per Widgets Board design guidelines. Only Carousel pagination dots can be present in the bottom ${WidgetContainer.widgetPadding}px margin of a widget.`;
3235
}

0 commit comments

Comments
 (0)