我想风格化mat-select输入。默认情况下,mat-select具有一些动画。如果我单击箭头并展开列表,则列表弹出窗口。我想删除此动画形式的垫选择输入。我想使用与本机html select相同的animtion弹出效果来实现mat-select输入。我不能使用本机html select。
<mat-form-field>
<mat-select>
<mat-option>option1</mat-option>
<mat-option>option2</mat-option>
<mat-option>option3</mat-option>
</mat-select>
</mat-form-field>
答案 0 :(得分:0)
我解决了我的问题:
.mat-select-panel {
&.ng-animating {
visibility: hidden;
}
<mat-form-field appearance="fill">
<select matNativeControl>
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option>
</select>
</mat-form-field>
<mat-form-field
appearance="outline"
class="select-form"
appDropDown
>
<mat-label>Label</mat-label>
<mat-select
panelClass="select-panel"
placeholder="placeholder"
>
<mat-option value="option1">option1</mat-option>
<mat-option value="option2">option2</mat-option>
<mat-option value="option3">option3</mat-option>
</mat-select>
</mat-form-field>
import {
Directive,
HostListener,
ElementRef,
AfterViewInit,
ContentChild,
Renderer2,
OnDestroy,
} from '@angular/core';
import {
Overlay,
ConnectedPositionStrategy,
OverlaySizeConfig,
} from '@angular/cdk/overlay';
import {
MatSelect,
MatOption,
MatOptionSelectionChange,
} from '@angular/material';
import { Subscription } from 'rxjs';
@Directive({
selector: '[appDropDown]',
})
export class DropDownDirective implements AfterViewInit, OnDestroy {
@ContentChild(MatSelect) select: MatSelect;
private overlaySubscription: Subscription;
private openPanelSubscription: Subscription;
private closePanelSubscription: Subscription;
private optionChangeSubscription: Subscription;
private stateChangeSubscription: Subscription;
private triggerValue: HTMLDivElement;
private triggerLabelClass = 'trigger-label';
private triggerOptionClass = 'trigger-option';
private openPanelClass = 'active';
constructor(
private el: ElementRef,
private overlayService: Overlay,
private renderer: Renderer2
) {}
@HostListener('window:resize', [])
onWindowResize(): void {
if (this.select.panelOpen) {
this.updateOverlaySize();
}
}
ngAfterViewInit(): void {
this.configTrigger();
this.configOverlay();
}
private configOverlay(): void {
this.overlaySubscription = this.select.overlayDir.attach.subscribe(() => {
this.setOverlayPositionStrategy();
this.updateOverlaySize();
});
}
private configTrigger(): void {
this.triggerValue = this.select.trigger.nativeElement.firstChild;
this.addClosePanelSubscription();
this.addOpenPanelSubscription();
this.addOptionChangeSubscription();
this.addStateChangeSubscription();
}
private addClosePanelSubscription(): void {
this.closePanelSubscription = this.select._closedStream.subscribe(() => {
this.renderer.removeClass(this.el.nativeElement, this.openPanelClass);
if (!this.select.empty) {
this.setTriggerStyleOption();
const option = this.select.selected as MatOption;
this.triggerValue.textContent = option.viewValue;
}
});
}
private addOpenPanelSubscription(): void {
this.openPanelSubscription = this.select._openedStream.subscribe(() => {
this.setTriggerStyleLabel();
this.renderer.addClass(this.el.nativeElement, this.openPanelClass);
this.triggerValue.textContent = this.select.placeholder;
});
}
private addOptionChangeSubscription(): void {
this.optionChangeSubscription = this.select.optionSelectionChanges.subscribe(
(option: MatOptionSelectionChange) => {
this.setTriggerStyleOption();
this.renderer.removeClass(this.el.nativeElement, this.openPanelClass);
this.triggerValue.textContent = option.source.viewValue;
}
);
}
private addStateChangeSubscription(): void {
this.stateChangeSubscription = this.select.stateChanges.subscribe(() => {
if (this.select.empty) {
this.setTriggerStyleLabel();
this.triggerValue.textContent = this.select.placeholder;
} else {
this.setTriggerStyleOption();
const option = this.select.selected as MatOption;
this.triggerValue.textContent = option.viewValue;
}
});
}
private setOverlayPositionStrategy(): void {
const positionConfig: ConnectedPositionStrategy = this.overlayService
.position()
.connectedTo(
this.el,
{ originX: 'start', originY: 'center' },
{ overlayX: 'start', overlayY: 'top' }
);
this.select.overlayDir.overlayRef.updatePositionStrategy(positionConfig);
}
private updateOverlaySize(): void {
const nativeFormField = this.el.nativeElement;
const sizeConfig: OverlaySizeConfig = {
width: nativeFormField.offsetWidth,
height: nativeFormField.offsetHeight,
minWidth: nativeFormField.minWidth,
minHeight: nativeFormField.minHeight,
};
this.select.overlayDir.overlayRef.updateSize(sizeConfig);
}
private setTriggerStyleLabel(): void {
this.renderer.removeClass(this.triggerValue, this.triggerOptionClass);
this.renderer.addClass(this.triggerValue, this.triggerLabelClass);
}
private setTriggerStyleOption(): void {
this.renderer.removeClass(this.triggerValue, this.triggerLabelClass);
this.renderer.addClass(this.triggerValue, this.triggerOptionClass);
}
ngOnDestroy(): void {
this.overlaySubscription.unsubscribe();
this.openPanelSubscription.unsubscribe();
this.closePanelSubscription.unsubscribe();
this.optionChangeSubscription.unsubscribe();
this.stateChangeSubscription.unsubscribe();
}
}
.select-form {
.mat-select {
position: absolute;
bottom: 30%;
text-align: left;
}
.mat-select-trigger {
position: relative;
left: 3px;
bottom: 2px;
font-size: 14px;
font-weight: 500;
.mat-select-placeholder {
color: #4b0082;
}
.mat-select-value,
.trigger-option {
color: #000;
}
.trigger-label {
color: #4b0082;
}
}
}
.mat-form-field-appearance-outline.active .mat-form-field-outline {
.mat-form-field-outline-start {
border-bottom-left-radius: 0px;
}
.mat-form-field-outline-end {
border-bottom-right-radius: 0px;
}
}
.select-panel.mat-select-panel {
&.ng-animating {
visibility: hidden;
}
position: absolute;
border: 1px solid #4b0082;
top: calc(12% - 1px);
box-shadow: none;
min-width: 100% !important;
border-top: 1px solid #bfbfbf;
border-radius: 0px 0px 5px 5px;
box-shadow: 0 3px 4px 0 transparentize(#000, 0.85) !important;
border-top-style: none;
animation-name: opening-panel;
animation-duration: 0.3s;
@keyframes opening-panel {
0% {
transform: scaleY(0.8);
}
100% {
transform: scaleY(1);
}
}
.mat-option.mat-selected:not(.mat-option-multiple) {
background-color: #c27fc1 !important;
}
.mat-option:hover:not(.mat-option-disabled) {
background-color: #c27fc1 !important;
}
.mat-option.mat-active {
background-color: transparent !important;
}
&::-webkit-scrollbar {
width: 5px;
&-track {
background: #bfbfbf;
border-radius: 6.5px;
margin-bottom: 10px;
}
&-thumb {
background: #bfbfbf;
border-radius: 6.5px;
}
}
}
.mat-select-panel {
.mat-option.mat-option.mat-selected:not(.mat-option-multiple) {
background: #c27fc1;
color: $text-color !important;
}
.mat-option {
font-weight: 600;
}
}
.mat-option.mat-option-disabled {
color: #4b0082;
font-weight: 500;
font-size: inherit;
.select-arrow {
position: absolute;
right: 0px;
top: 10px;
}
}
.table-filter-panel.mat-select-panel {
position: absolute;
left: -5px;
top: 27px;
box-shadow: none;
min-width: calc(100% + 32px);
border: 1px solid #4b0082;
border-radius: 0 0 1px 1px;
box-shadow: 0 3px 4px 0 transparentize(#000, 0.85) !important;
border-top-color: #c27fc1;
.mat-option {
color: #bfbfbf;
&.mat-selected:not(.mat-option-multiple) {
background-color: #c27fc1 !important;
}
&:hover:not(.mat-option-disabled) {
background-color: #c27fc1 !important;
}
&.mat-active {
background-color: transparent !important;
}
}
&::-webkit-scrollbar {
width: 5px;
&-track {
background: #bfbfbf;
border-radius: 6.5px;
margin-bottom: 10px;
}
&-thumb {
background: #bfbfbf;
border-radius: 6.5px;
}
}
}