Приложение My Angular Material v18 позволяет пользователю устанавливать свою тему, но одна группа компонентов, «контроль заказа», имеет два семантических цвета: синий для «купить»; и красный для «продажи» (аналогично синему для «холодно» и красному для «жарко» в приложении погоды), которые не зависят от темы. Вот HTML-версия, которая делает то, что должна, за которой следует раздел Angular Material, который не меняет цвет.
Как я могу заставить элемент управления заказом Angular Material менять семантические цвета при выборе КУПИТЬ/ПРОДАТЬ, аналогично версии HTML?
Вот HTML-версия:
<div class = "order-control">
<div>
<span [class] = "buyColor()" (click) = "isSell=false">BUY</span>
<span [class] = "sellColor()" (click) = "isSell=true">SELL</span>
</div>
<div>
<label for = "units">Units</label>
<input
[class] = "getColor()"
type = "range"
id = "units"
name = "units"
[min] = "unitsMin"
[max] = "unitsMax"
[(ngModel)] = "units"/>
</div>
<div>
<label for = "price">Price</label>
<input
[class] = "getColor()"
type = "range"
id = "price"
name = "price"
[min] = "priceMin"
[max] = "priceMax"
[(ngModel)] = "price"/>
</div>
<div>
<button [class] = "getColor()" type = "button">Submit order</button>
</div>
</div>
А вот аналогичная версия с Angular Material, но цвета переключателя, ползунков и кнопки отправки должны меняться при выборе «стороны» ордера (т. е. покупки или продажи):
<div class = "order-control">
<div>
<mat-button-toggle-group name = "side" [(ngModel)] = "isSell">
<mat-button-toggle [value] = "false">BUY</mat-button-toggle>
<mat-button-toggle [value] = "true">SELL</mat-button-toggle>
</mat-button-toggle-group>
</div>
<div>
<label for = "units">Units</label>
<mat-slider
[max] = "unitsMax"
[min] = "unitsMin"
[step] = "unitsStep"
discrete showTickMarks>
<input matSliderThumb [(ngModel)] = "units" #unitsSlider />
</mat-slider>
</div>
<div>
<label for = "price">Price</label>
<mat-slider
[max] = "priceMax"
[min] = "priceMin"
[step] = "priceStep"
discrete showTickMarks>
<input matSliderThumb [(ngModel)] = "price" #priceSlider />
</mat-slider>
</div>
<div>
<button mat-flat-button>Submit Order</button>
</div>
</div>
CSS
.order-control {
display: flex;
flex-direction: column;
justify-content: center;
.sell {
color: red;
accent-color: red;
}
.buy {
color: blue;
accent-color: blue;
}
}
Машинопись
@Component({
selector: 'app-root',
standalone: true,
imports: [ FormsModule, MatButtonModule, MatButtonToggleModule, MatSliderModule ],
templateUrl: './main.html',
styleUrl: './main.css',
})
export class App {
isSell: boolean = false;
units = 1;
unitsMin = 1;
unitsMax = 10;
unitsStep = 1;
price = 500;
priceMin = 0;
priceMax = 1000;
priceStep = 25;
buyColor() {
return this.isSell ? '' : 'buy';
}
sellColor() {
return this.isSell ? 'sell' : '';
}
getColor() {
return this.isSell ? 'sell' : 'buy';
}
}
Вот рабочий образец.






Я бы советовал не делать этого, поскольку это нарушит дизайн: когда вы реализуете систему дизайна, нет «независимого компонента», все должно соответствовать предоставленному дизайну.
При этом просто примените свой класс условно?
<mat-button-toggle [value] = "true" [class.sell] = "isSell">SELL</mat-button-toggle>
Что касается условного класса, да, он меняет цвет текста, как и HTML, но было бы лучше, если бы изменился фон. И ползунки, похоже, не меняются при таких изменениях.
Вы можете попытаться создать собственную тему для конкретных компонентов, например:
@use '@angular/material' as mat;
@include mat.core();
$custom-palette: (
50: var(--Your-colors),
...
)
$custom-primary: mat.define-palette($custom-palette, 500)
$theme: mat.define-light-theme((
color: (
primary: $custom-primary,
accent: $custom-accent,
),
))
$buy: mat.define-palette($theme, 500)
@include mat-button-theme($buy)
.buy-theme {
@include mat-button-theme($buy);
}
Затем добавьте сюда логику, которая назначает переменные CSS --Your-colors
Проблема с Материалом 2 заключается в том, что есть три цвета: основной, акцентный и предупреждающий... и мне нужно еще два: купить; и, продать. Похоже, что в Material 3 будет еще несколько, так что это может быть вариант, когда все компоненты Angular Material поддерживают M3.
Насколько мне известно, все компоненты Angular Material поддерживают M3.
На более полном примере Ч. Райдера я понимаю, что вы (оба) предлагаете: используйте основные цвета «темы покупки» или «темы продажи» в «компоненте заказа», чтобы нам не нужно ничего, кроме «компонента заказа». первичная палитра. Спасибо Кибе и Ч!
Чтобы добиться желаемого эффекта, добавьте в файл styles.scss следующее:
@use '@angular/material' as mat;
@include mat.core();
$my-theme: mat.define-theme((
color: (
primary: mat.$violet-palette
)
));
html {
@include mat.all-component-themes($my-theme);
}
$blue-theme: mat.define-theme(
(
color: (
primary: mat.$blue-palette
)
)
);
$red-theme: mat.define-theme(
(
color: (
primary: mat.$red-palette
)
)
);
.blue {
@include mat.all-component-colors($blue-theme);
}
.red {
@include mat.all-component-colors($red-theme);
}
Затем измените свой order-control div следующим образом:
<div class = "order-control" [class] = "isSell ? 'red' : 'blue'">
Удачи с вашим проектом.
Вот PoC.
Действительно, это работает! На вашем примере я понимаю, что вы (и Кибе) предлагаете: используйте основные цвета «темы покупки» или «темы продажи» в «компоненте заказа», поэтому не нужно ничего, кроме «основной» палитры. .
Да, я слышу, что вы говорите @MGX — проблема с Материалом 2 заключается в том, что есть три цвета: основной, акцентный и предупреждающий… и мне нужно еще два: купить; и, продать. Похоже, что в Material 3 будет еще несколько, так что это может быть вариант, когда все компоненты Angular Material поддерживают M3.