Семантические цвета в компоненте Angular Material

Приложение 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';
  }
}

Вот рабочий образец.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
2
0
63
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я бы советовал не делать этого, поскольку это нарушит дизайн: когда вы реализуете систему дизайна, нет «независимого компонента», все должно соответствовать предоставленному дизайну.

При этом просто примените свой класс условно?

<mat-button-toggle [value] = "true" [class.sell] = "isSell">SELL</mat-button-toggle>

Да, я слышу, что вы говорите @MGX — проблема с Материалом 2 заключается в том, что есть три цвета: основной, акцентный и предупреждающий… и мне нужно еще два: купить; и, продать. Похоже, что в Material 3 будет еще несколько, так что это может быть вариант, когда все компоненты Angular Material поддерживают M3.

Jan Nielsen 02.08.2024 15:06

Что касается условного класса, да, он меняет цвет текста, как и HTML, но было бы лучше, если бы изменился фон. И ползунки, похоже, не меняются при таких изменениях.

Jan Nielsen 02.08.2024 15:10

Вы можете попытаться создать собственную тему для конкретных компонентов, например:

@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.

Jan Nielsen 02.08.2024 15:17

Насколько мне известно, все компоненты Angular Material поддерживают M3.

Ch Ryder 03.08.2024 21:06

На более полном примере Ч. Райдера я понимаю, что вы (оба) предлагаете: используйте основные цвета «темы покупки» или «темы продажи» в «компоненте заказа», чтобы нам не нужно ничего, кроме «компонента заказа». первичная палитра. Спасибо Кибе и Ч!

Jan Nielsen 04.08.2024 14:43
Ответ принят как подходящий

Чтобы добиться желаемого эффекта, добавьте в файл 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.

Действительно, это работает! На вашем примере я понимаю, что вы (и Кибе) предлагаете: используйте основные цвета «темы покупки» или «темы продажи» в «компоненте заказа», поэтому не нужно ничего, кроме «основной» палитры. .

Jan Nielsen 04.08.2024 14:45

Другие вопросы по теме