EDIT 2: The issue has been fixed by the amazing CDK Team!
EDIT: As this seems to be quite strange behaviour, I have for now added an issue in the official CDK repository. Feel free to suggest any ideas or workourounds, however.
I have different types of elements in my *cdkDropList
that need different placholder hights when dragging them around. Since the array has objects with a property type
, I added those types as CSS classes and tried to add them dynamically using [ngClass]
. However, these dynamically generated classes behave differently than when I'm setting them as "regular" CSS classes.
This is what happens, when I set the classes dynamically:
The placeholder and the elements in the dropList
overlap. Here's the relevant code:
example.component.ts
contentItems: ContentItem[] = [
{ type: 'text', /* more props */ },
{ type: 'text', /* more props */ },
{ type: 'image', /* more props */ }
];
example.component.html
<div *ngFor="let item of contentItems" class="editor-item" cdkDrag>
<div [ngClass]="['dropzone-placeholder', item.type]" *cdkDragPlaceholder>
<p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
</div>
<app-language-tab-editor *ngIf="item.type === 'text'"></app-language-tab-editor>
<app-image-upload *ngIf="item.type === 'image'"></app-image-upload>
</div>
example.component.scss
$dropzone-placeholder-dark: #00973B;
$dropzone-placeholder-light: #00973B0D;
$text-placeholder-height: 135px;
$image-placeholder-height: 375px;
.dropzone-placeholder {
border: 1px dashed $dropzone-placeholder-dark;
color: $dropzone-placeholder-dark;
background: $dropzone-placeholder-light;
&.text {
height: $text-placeholder-height;
}
&.image {
height: $image-placeholder-height;
}
}
I currently only have two different types, but the goal is to make it easily expandable to add more later on. I have also already tried to instead use class="dropzone-placeholder {{ item.type }}"
as well as [class]="'dropzone-placeholder ' + item.type"
, to no avail.
After further testing I have also found out, that it generally doesn't work using [ngClass]
, even if we don't use a variable. Using [ngClass]="['dropzone-placeholder', 'text']"
didn't work either.
This is the expected behaviour:
The placeholder and the elements in the dropList
don't overlap and are instead placed properly below each other. This behaviour can currently only be achieved by setting the classes regularily, but the HTML is rather unpleasant to look at, since the code would get messily redundant in the future.
example.component.html
<div *ngFor="let item of contentItems" class="editor-item" cdkDrag>
<div *ngIf="item.type === 'text'">
<div class="dropzone-placeholder reorder text" *cdkDragPlaceholder>
<p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
</div>
</div>
<div *ngIf="item.type === 'image'">
<div class="dropzone-placeholder reorder image" *cdkDragPlaceholder>
<p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
</div>
</div>
<app-language-tab-editor *ngIf="item.type === 'text'"></app-language-tab-editor>
<app-image-upload *ngIf="item.type === 'image'"></app-image-upload>
</div>
Why is the CDK behaving differently when the classes are not set the traditional way? And how can I avoid writing the redundant workaround mentioned above?