feat(project-editor): migrate theme section to Select/ColorPicker/SectionCard
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,35 +1,20 @@
|
|||||||
@if (bootstrap(); as bootstrap) {
|
@if (bootstrap(); as bootstrap) {
|
||||||
<section class="editor-section-card">
|
<app-section-card [title]="'builder.theme' | translate">
|
||||||
<h2>{{ 'builder.theme' | translate }}</h2>
|
|
||||||
<div class="editor-grid two">
|
<div class="editor-grid two">
|
||||||
<app-form-field [label]="'builder.primaryColor' | translate" [hint]="'builder.primaryColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.primary" (ngModelChange)="updatePalette('primary', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.primaryColor' | translate" [hint]="'builder.primaryColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.primary" (ngModelChange)="updatePalette('primary', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.secondaryColor' | translate" [hint]="'builder.secondaryColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.secondary" (ngModelChange)="updatePalette('secondary', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.secondaryColor' | translate" [hint]="'builder.secondaryColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.secondary" (ngModelChange)="updatePalette('secondary', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.backgroundColor' | translate" [hint]="'builder.backgroundColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.backgroundPrimary" (ngModelChange)="updatePalette('backgroundPrimary', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.backgroundColor' | translate" [hint]="'builder.backgroundColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.backgroundPrimary" (ngModelChange)="updatePalette('backgroundPrimary', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.surfaceColor' | translate" [hint]="'builder.surfaceColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.backgroundSecondary" (ngModelChange)="updatePalette('backgroundSecondary', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.surfaceColor' | translate" [hint]="'builder.surfaceColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.backgroundSecondary" (ngModelChange)="updatePalette('backgroundSecondary', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.textColor' | translate" [hint]="'builder.textColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.textPrimary" (ngModelChange)="updatePalette('textPrimary', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.textColor' | translate" [hint]="'builder.textColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.textPrimary" (ngModelChange)="updatePalette('textPrimary', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.successColor' | translate" [hint]="'builder.successColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.success" (ngModelChange)="updatePalette('success', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.successColor' | translate" [hint]="'builder.successColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.success" (ngModelChange)="updatePalette('success', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.warningColor' | translate" [hint]="'builder.warningColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.warning" (ngModelChange)="updatePalette('warning', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.warningColor' | translate" [hint]="'builder.warningColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.warning" (ngModelChange)="updatePalette('warning', $event)" /></app-form-field>
|
||||||
<app-form-field [label]="'builder.dangerColor' | translate" [hint]="'builder.dangerColorDesc' | translate"><input type="color" [ngModel]="bootstrap.theme.palette.danger" (ngModelChange)="updatePalette('danger', $event)" /></app-form-field>
|
<app-form-field [label]="'builder.dangerColor' | translate" [hint]="'builder.dangerColorDesc' | translate"><app-color-picker [ngModel]="bootstrap.theme.palette.danger" (ngModelChange)="updatePalette('danger', $event)" /></app-form-field>
|
||||||
<label>
|
<app-form-field [label]="'builder.themeModeLabel' | translate" [hint]="'builder.themeModeDesc' | translate">
|
||||||
<span>{{ 'builder.themeModeLabel' | translate }}</span>
|
<app-select [options]="themeModeSelectOptions()" [ngModel]="bootstrap.theme.mode" (ngModelChange)="updateThemeMode($event)" />
|
||||||
<small class="field-desc">{{ 'builder.themeModeDesc' | translate }}</small>
|
</app-form-field>
|
||||||
<select [ngModel]="bootstrap.theme.mode" (ngModelChange)="updateThemeMode($event)">
|
<app-form-field [label]="'builder.siteLayoutLabel' | translate" [hint]="'builder.siteLayoutDesc' | translate">
|
||||||
@for (option of themeModeOptions; track option.value) {
|
<app-select [options]="siteLayoutSelectOptions()" [ngModel]="bootstrap.layout?.type || 'default'" (ngModelChange)="updateSiteLayout($event)" />
|
||||||
<option [value]="option.value">{{ option.labelKey | translate }}</option>
|
</app-form-field>
|
||||||
}
|
|
||||||
</select>
|
|
||||||
<small class="field-desc">{{ themeModeDescKey(bootstrap.theme.mode) | translate }}</small>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span>{{ 'builder.siteLayoutLabel' | translate }}</span>
|
|
||||||
<small class="field-desc">{{ 'builder.siteLayoutDesc' | translate }}</small>
|
|
||||||
<select [ngModel]="bootstrap.layout?.type || 'default'" (ngModelChange)="updateSiteLayout($event)">
|
|
||||||
@for (option of siteLayoutOptions; track option.value) {
|
|
||||||
<option [value]="option.value">{{ option.labelKey | translate }}</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
<small class="field-desc">{{ siteLayoutDescKey(bootstrap.layout?.type || 'default') | translate }}</small>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</app-section-card>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { ProjectEditorFacade } from '../facade/project-editor.facade';
|
import { ProjectEditorFacade } from '../facade/project-editor.facade';
|
||||||
import { TranslatePipe } from '../../../i18n/translate.pipe';
|
import { TranslatePipe } from '../../../i18n/translate.pipe';
|
||||||
|
import { TranslateService } from '../../../i18n/translate.service';
|
||||||
import { PlatformLayoutType, ThemePaletteConfig } from '../../../shared/models/config';
|
import { PlatformLayoutType, ThemePaletteConfig } from '../../../shared/models/config';
|
||||||
import { FormFieldComponent } from '../../../shared/ui/form-field/form-field.component';
|
import { FormFieldComponent } from '../../../shared/ui/form-field/form-field.component';
|
||||||
|
import { SectionCardComponent } from '../../../shared/ui/section-card/section-card.component';
|
||||||
|
import { SelectComponent, SelectOption } from '../../../shared/ui/select/select.component';
|
||||||
|
import { ColorPickerComponent } from '../../../shared/ui/color-picker/color-picker.component';
|
||||||
|
|
||||||
export interface ThemeModeOption {
|
export interface ThemeModeOption {
|
||||||
value: 'light' | 'dark' | 'system';
|
value: 'light' | 'dark' | 'system';
|
||||||
@@ -20,13 +24,14 @@ export interface SiteLayoutOption {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-project-editor-theme-section',
|
selector: 'app-project-editor-theme-section',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [FormsModule, TranslatePipe, FormFieldComponent],
|
imports: [FormsModule, TranslatePipe, FormFieldComponent, SectionCardComponent, SelectComponent, ColorPickerComponent],
|
||||||
templateUrl: './theme-section.component.html',
|
templateUrl: './theme-section.component.html',
|
||||||
styleUrls: ['./section.shared.scss'],
|
styleUrls: ['./section.shared.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ProjectEditorThemeSectionComponent {
|
export class ProjectEditorThemeSectionComponent {
|
||||||
private readonly facade = inject(ProjectEditorFacade);
|
private readonly facade = inject(ProjectEditorFacade);
|
||||||
|
private readonly translate = inject(TranslateService);
|
||||||
readonly bootstrap = this.facade.bootstrap;
|
readonly bootstrap = this.facade.bootstrap;
|
||||||
|
|
||||||
readonly themeModeOptions: ThemeModeOption[] = [
|
readonly themeModeOptions: ThemeModeOption[] = [
|
||||||
@@ -42,6 +47,22 @@ export class ProjectEditorThemeSectionComponent {
|
|||||||
{ value: 'minimal', labelKey: 'builder.siteLayoutMinimal', descKey: 'builder.siteLayoutMinimalDesc' },
|
{ value: 'minimal', labelKey: 'builder.siteLayoutMinimal', descKey: 'builder.siteLayoutMinimalDesc' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
readonly themeModeSelectOptions = computed<SelectOption[]>(() =>
|
||||||
|
this.themeModeOptions.map(option => ({
|
||||||
|
value: option.value,
|
||||||
|
label: this.translate.t(option.labelKey),
|
||||||
|
description: this.translate.t(option.descKey)
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
readonly siteLayoutSelectOptions = computed<SelectOption[]>(() =>
|
||||||
|
this.siteLayoutOptions.map(option => ({
|
||||||
|
value: option.value,
|
||||||
|
label: this.translate.t(option.labelKey),
|
||||||
|
description: this.translate.t(option.descKey)
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
updatePalette<K extends keyof ThemePaletteConfig>(key: K, value: string): void {
|
updatePalette<K extends keyof ThemePaletteConfig>(key: K, value: string): void {
|
||||||
this.facade.updateBootstrap(current => ({
|
this.facade.updateBootstrap(current => ({
|
||||||
...current,
|
...current,
|
||||||
@@ -62,12 +83,4 @@ export class ProjectEditorThemeSectionComponent {
|
|||||||
layout: { ...current.layout, type: type as PlatformLayoutType }
|
layout: { ...current.layout, type: type as PlatformLayoutType }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
themeModeDescKey(mode: string): string {
|
|
||||||
return this.themeModeOptions.find(option => option.value === mode)?.descKey ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
siteLayoutDescKey(type: string): string {
|
|
||||||
return this.siteLayoutOptions.find(option => option.value === type)?.descKey ?? '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user