- Move the guard to scripts/check-tokens.sh; regex now catches hex + rgb()/hsl() (was hex-only) across ALL src/app components (was three ui/layout dirs). `token-ok` marker suppresses justified false positives; px stays out of scope (documented in the script). - Zero exclusions: debug-state's dark code-editor palette moves to --app-devpanel-* tokens in styles.scss (the one exempt file), dropping its --exclude hole. - Tokenize remaining hits: site-footer border via color-mix; three brief border widths via --rhc-border-width-* (new --rhc-border-width-lg: 3px). Verified: planted violation fails the guard; GREEN + test-storybook:ci. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
2.3 KiB
TypeScript
54 lines
2.3 KiB
TypeScript
import { Component, computed, input, output } from '@angular/core';
|
|
import { RichTextBlock } from '@shared/kernel/rich-text';
|
|
import { RichTextEditorComponent, PlaceholderOption } from '@shared/ui/rich-text-editor/rich-text-editor.component';
|
|
import { ButtonComponent } from '@shared/ui/button/button.component';
|
|
import { LetterBlock } from '@brief/domain/brief';
|
|
|
|
/** Molecule: one block in a section — its editor plus provenance + block controls.
|
|
Presentational: emits content/remove/move events; the section maps them to messages. */
|
|
@Component({
|
|
selector: 'app-letter-block',
|
|
imports: [RichTextEditorComponent, ButtonComponent],
|
|
styles: [`
|
|
:host{display:block}
|
|
.block{border-inline-start:var(--rhc-border-width-lg) solid var(--rhc-color-border-subtle);padding-inline-start:var(--rhc-space-max-md)}
|
|
.meta{display:flex;justify-content:space-between;align-items:center;gap:var(--rhc-space-max-md);margin-block-end:var(--rhc-space-max-sm)}
|
|
.controls{display:flex;gap:var(--rhc-space-max-sm)}
|
|
`],
|
|
template: `
|
|
<div class="block">
|
|
<div class="meta">
|
|
<span class="app-text-subtle">{{ provenance() }}</span>
|
|
@if (editable()) {
|
|
<span class="controls">
|
|
<app-button variant="subtle" (click)="moved.emit(-1)" i18n="@@brief.block.moveUp">Omhoog</app-button>
|
|
<app-button variant="subtle" (click)="moved.emit(1)" i18n="@@brief.block.moveDown">Omlaag</app-button>
|
|
<app-button variant="subtle" (click)="removed.emit()" i18n="@@brief.block.remove">Verwijderen</app-button>
|
|
</span>
|
|
}
|
|
</div>
|
|
<app-rich-text-editor
|
|
[content]="block().content"
|
|
[placeholders]="placeholders()"
|
|
[editable]="editable()"
|
|
(contentChanged)="contentChanged.emit($event)" />
|
|
</div>
|
|
`,
|
|
})
|
|
export class LetterBlockComponent {
|
|
block = input.required<LetterBlock>();
|
|
placeholders = input<readonly PlaceholderOption[]>([]);
|
|
editable = input(false);
|
|
contentChanged = output<RichTextBlock>();
|
|
removed = output<void>();
|
|
moved = output<-1 | 1>();
|
|
|
|
protected provenance = computed(() => {
|
|
const b = this.block();
|
|
if (b.type === 'freeText') return $localize`:@@brief.provenance.free:Vrije tekst`;
|
|
return b.edited
|
|
? $localize`:@@brief.provenance.edited:Aangepaste standaardtekst`
|
|
: $localize`:@@brief.provenance.standard:Standaardtekst`;
|
|
});
|
|
}
|