Skip to content
Snippets Groups Projects
Commit 13a283ce authored by rhenck's avatar rhenck
Browse files

[editor] Improve TextEditor toolbar layout and functionality

- Reordered the buttons to make it look nicer (but still make sence 
logically)
- Put some more divs with flex layouting to prevent elements moving 
unexpextedly.
- Changed color and list inputs to split-buttons. Those compone a button 
with a dropdown.
- The editor now saves the set color and  it can be applied to 
subsequent selections as well.
parent f5e0c106
No related branches found
No related tags found
No related merge requests found
div.ProseMirror {
height: 450px;
min-height: 350px;
border: 1px solid;
overflow: auto;
}
app-rich-text-editor button {
min-width: unset !important;
width: 50px;
app-rich-text-editor button.active {
background-color: lightgrey;
}
app-rich-text-editor .editor-button-formfield-align button {
vertical-align: top !important;
margin-top: 10px !important;
app-rich-text-editor mat-form-field {
width: 100px;
margin: 0 8px;
}
app-rich-text-editor button.active {
background-color: lightgrey;
app-rich-text-editor mat-form-field.mat-form-field-type-mat-select {
margin-top: 4px;
}
app-rich-text-editor mat-form-field {
width: 120px;
margin: 0 10px;
app-rich-text-editor .editor-controls-first-line {
height: 50px;
margin-bottom: 5px;
}
app-rich-text-editor .editor-control-line {
app-rich-text-editor .editor-controls-second-line {
height: 50px;
margin-bottom: 5px;
}
......@@ -49,3 +47,43 @@ app-rich-text-editor .editor-control-line {
font-weight: normal;
font-size: 16px;
}
.editor-controls-first-line .combo-button {
margin-top: 5px;
margin-left: 10px;
}
.editor-controls-first-line .combo-button mat-select {
margin-top: 25%;
}
.editor-controls-second-line .combo-button {
margin-bottom: 10px;
border-radius: 10px;
}
.editor-controls-second-line .combo-button mat-select {
margin-top: 25%;
margin-left: -10px;
}
.button-group {
margin-right: 10px;
}
.button-group button {
margin: 0 -5px;
}
.editor-controls-first-line .button-group {
margin-top: 8px;
}
.editor-controls-second-line .button-group {
margin-right: 25px;
}
.font-size-dropdown {
width: 70px;
}
.special-chars-button {
margin-left: 25px;
}
<div class="editor-control-line" fxLayout="row">
<div class="editor-button-formfield-align">
<button mat-icon-button matTooltip="Fett" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('bold')"
(click)="toggleBold()">
<mat-icon>format_bold</mat-icon>
</button>
<button mat-icon-button matTooltip="Kursiv" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('italic')"
(click)="toggleItalic()">
<mat-icon>format_italic</mat-icon>
</button>
<button mat-icon-button matTooltip="Unterstrichen" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('underline')"
(click)="toggleUnderline()" style="text-decoration: underline">
<mat-icon>format_underlined</mat-icon>
</button>
<button mat-icon-button matTooltip="Hochgestellt" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('superscript')"
(click)="toggleSuperscript()">
<mat-icon>superscript</mat-icon>
</button>
<button mat-icon-button matTooltip="Tiefgestellt" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('subscript')"
(click)="toggleSubscript()">
<mat-icon>subscript</mat-icon>
</button>
<button mat-icon-button matTooltip="Durchgestrichen" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('strike')"
(click)="toggleStrike()">
<mat-icon>strikethrough_s</mat-icon>
</button>
</div>
<div>
<mat-form-field>
<div fxLayout="column">
<div class="editor-controls-first-line" fxLayout="row">
<div fxLayout="row" class="button-group">
<button mat-icon-button matTooltip="Fett" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('bold')"
(click)="toggleBold()">
<mat-icon>format_bold</mat-icon>
</button>
<button mat-icon-button matTooltip="Kursiv" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('italic')"
(click)="toggleItalic()">
<mat-icon>format_italic</mat-icon>
</button>
<button mat-icon-button matTooltip="Unterstrichen" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('underline')"
(click)="toggleUnderline()" style="text-decoration: underline">
<mat-icon>format_underlined</mat-icon>
</button>
<button mat-icon-button matTooltip="Hochgestellt" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('superscript')"
(click)="toggleSuperscript()">
<mat-icon>superscript</mat-icon>
</button>
<button mat-icon-button matTooltip="Tiefgestellt" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('subscript')"
(click)="toggleSubscript()">
<mat-icon>subscript</mat-icon>
</button>
<button mat-icon-button matTooltip="Durchgestrichen" [matTooltipPosition]="'above'" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('strike')"
(click)="toggleStrike()">
<mat-icon>strikethrough_s</mat-icon>
</button>
</div>
<mat-form-field class="font-size-dropdown">
<mat-label>Schriftgröße</mat-label>
<mat-select [value]="editor.getAttributes('textStyle').fontSize?.toString() || '16'"
(valueChange)="applyFontSize($event)">
......@@ -51,143 +51,35 @@
<mat-option value="36">36px</mat-option>
</mat-select>
</mat-form-field>
<div class="combo-button" fxLayout="row"
[style.background-color]="selectedFontColor">
<button mat-icon-button matTooltip="Textfarbe"
(click)="applyFontColor()">
<mat-icon>format_color_text</mat-icon>
</button>
<mat-select (click)="textColorInput.click()"></mat-select>
<input matInput type="color" #textColorInput hidden
(input)="selectedFontColor = $any($event.target).value; applyFontColor()">
</div>
<div class="combo-button" fxLayout="row"
[style.background-color]="selectedHighlightColor">
<button mat-icon-button matTooltip="Texthintergrund"
(click)="applyHighlightColor()">
<mat-icon>format_color_fill</mat-icon>
</button>
<mat-select (click)="textHighlightColorInput.click()"></mat-select>
<input matInput type="color" #textHighlightColorInput hidden
(input)="selectedHighlightColor = $any($event.target).value; applyHighlightColor()">
</div>
<mat-form-field>
<mat-label>Textfarbe</mat-label>
<input matInput type="color"
[value]="editor.getAttributes('textStyle').color"
(input)="applyColor($any($event.target).value)">
</mat-form-field>
<mat-form-field>
<mat-label>Hintergrundfarbe</mat-label>
<input matInput type="color"
[value]="editor.getAttributes('highlight').color"
(input)="applyHighlight($any($event.target).value)">
</mat-form-field>
</div>
</div>
<div class="editor-button-formfield-align" fxLayout="row" fxLayoutAlign="space-between">
<div>
<button mat-icon-button matTooltip="Linksbündig" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'left' })"
(click)="alignText('left')">
<mat-icon>format_align_left</mat-icon>
</button>
<button mat-icon-button matTooltip="Rechtsbündig" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'right' })"
(click)="alignText('right')">
<mat-icon>format_align_right</mat-icon>
</button>
<button mat-icon-button matTooltip="Zentriert" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'center' })"
(click)="alignText('center')">
<mat-icon>format_align_center</mat-icon>
</button>
<button mat-icon-button matTooltip="Blocksatz" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'justify' })"
(click)="alignText('justify')">
<mat-icon>format_align_justify</mat-icon>
</button>
</div>
<div>
<button mat-icon-button matTooltip="Einrücken" [matTooltipShowDelay]="300"
(click)="indent()">
<mat-icon>format_indent_increase</mat-icon>
</button>
<button mat-icon-button matTooltip="Einrückung verringern" [matTooltipShowDelay]="300"
(click)="outdent()">
<mat-icon>format_indent_decrease</mat-icon>
</button>
</div>
<div>
<button mat-icon-button matTooltip="Aufzählung" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('bulletList')"
(click)="toggleBulletList()">
<mat-icon>format_list_bulleted</mat-icon>
</button>
<button mat-icon-button matTooltip="Aufzählung (nummeriert)" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('orderedList')"
(click)="togleOrderedList()">
<mat-icon>format_list_numbered</mat-icon>
</button>
</div>
<button mat-icon-button matTooltip="Sonderzeichen" [matTooltipShowDelay]="300"
[matMenuTriggerFor]="specialCharsMenu">
<mat-icon>emoji_symbols</mat-icon>
</button>
<mat-menu #specialCharsMenu="matMenu" yPosition="above">
<button mat-button (click)="insertSpecialChar('&nbsp;')"
[matTooltip]="'Geschütztes Leerzeichen'">&blank;</button>
<button mat-button (click)="insertSpecialChar('&female;')">&female;</button>
<button mat-button (click)="insertSpecialChar('&male;')">&male;</button>
<button mat-button (click)="insertSpecialChar('&micro;')">&micro;</button>
<br>
<button mat-button (click)="insertSpecialChar('&ccedil;')">&ccedil;</button>
<button mat-button (click)="insertSpecialChar('&Ccedil;')">&Ccedil;</button>
<button mat-button (click)="insertSpecialChar('&AElig;')">&AElig;</button>
<br>
<button mat-button (click)="insertSpecialChar('&lsaquo;')">&lsaquo;</button>
<button mat-button (click)="insertSpecialChar('&rsaquo;')">&rsaquo;</button>
<button mat-button (click)="insertSpecialChar('&laquo;')">&laquo;</button>
<button mat-button (click)="insertSpecialChar('&raquo;')">&raquo;</button>
<br>
<button mat-button (click)="insertSpecialChar('&cent;')">&cent;</button>
<button mat-button (click)="insertSpecialChar('&pound;')">&pound;</button>
<button mat-button (click)="insertSpecialChar('&yen;')">&yen;</button>
<br>
<button mat-button (click)="insertSpecialChar('&copy;')">&copy;</button>
<button mat-button (click)="insertSpecialChar('&reg;')">&reg;</button>
<button mat-button (click)="insertSpecialChar('&trade;')">&trade;</button>
<br>
<button mat-button (click)="insertSpecialChar('&le;')">&le;</button>
<button mat-button (click)="insertSpecialChar('&ge;')">&ge;</button>
<button mat-button (click)="insertSpecialChar('&fpartint;')">&fpartint;</button>
<button mat-button (click)="insertSpecialChar('&sum;')">&sum;</button>
<button mat-button (click)="insertSpecialChar('&isin;')">&isin;</button>
<button mat-button (click)="insertSpecialChar('&notin;')">&notin;</button>
<button mat-button (click)="insertSpecialChar('&radic;')">&radic;</button>
<button mat-button (click)="insertSpecialChar('&infin;')">&infin;</button>
<br>
<button mat-button (click)="insertSpecialChar('&spades;')">&spades;</button>
<button mat-button (click)="insertSpecialChar('&clubs;')">&clubs;</button>
<button mat-button (click)="insertSpecialChar('&hearts;')">&hearts;</button>
<button mat-button (click)="insertSpecialChar('&diams;')">&diams;</button>
</mat-menu>
<mat-form-field>
<mat-label>Überschrift</mat-label>
<mat-select [value]="editor.getAttributes('heading').level?.toString() || ''"
(valueChange)="toggleHeading($event)">
<mat-option value="1">H1</mat-option>
<mat-option value="2">H2</mat-option>
<mat-option value="3">H3</mat-option>
<mat-option value="4">H4</mat-option>
<mat-option value="">Paragraph</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button [matMenuTriggerFor]="optionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #optionsMenu="matMenu">
<mat-form-field>
<mat-label>Aufzählungszeichen</mat-label>
<mat-select [value]="editor.getAttributes('bulletList').listStyle"
(click)="$any($event).stopPropagation()"
(valueChange)="applyListStyle('bulletList', $event)">
<mat-option value="disc">disc</mat-option>
<mat-option value="circle">circle</mat-option>
<mat-option value="square">square</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Aufzählungsnummerierung</mat-label>
<mat-select [value]="editor.getAttributes('orderedList').listStyle"
(click)="$any($event).stopPropagation()"
(valueChange)="applyListStyle('orderedList', $event)">
<mat-option value="decimal">decimal</mat-option>
<mat-option value="lower-latin">lower-latin</mat-option>
<mat-option value="upper-latin">upper-latin</mat-option>
<mat-option value="lower-roman">lower-roman</mat-option>
<mat-option value="upper-roman">upper-roman</mat-option>
<mat-option value="lower-greek">lower-greek</mat-option>
<mat-label>Absatztyp</mat-label>
<mat-select [value]="editor.getAttributes('heading').level?.toString() || ''"
(valueChange)="toggleHeading($event)">
<mat-option value="1">H1</mat-option>
<mat-option value="2">H2</mat-option>
<mat-option value="3">H3</mat-option>
<mat-option value="4">H4</mat-option>
<mat-option value="">Paragraph</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
......@@ -200,7 +92,130 @@
<mat-option value="20">20px</mat-option>
</mat-select>
</mat-form-field>
</mat-menu>
</div>
<div class="editor-controls-second-line" fxLayout="row">
<div class="button-group" fxLayout="row">
<button mat-icon-button matTooltip="Linksbündig" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'left' })"
(click)="alignText('left')">
<mat-icon>format_align_left</mat-icon>
</button>
<button mat-icon-button matTooltip="Rechtsbündig" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'right' })"
(click)="alignText('right')">
<mat-icon>format_align_right</mat-icon>
</button>
<button mat-icon-button matTooltip="Zentriert" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'center' })"
(click)="alignText('center')">
<mat-icon>format_align_center</mat-icon>
</button>
<button mat-icon-button matTooltip="Blocksatz" [matTooltipShowDelay]="300"
[class.active]="editor.isActive({ textAlign: 'justify' })"
(click)="alignText('justify')">
<mat-icon>format_align_justify</mat-icon>
</button>
</div>
<div class="button-group" fxLayout="row">
<button mat-icon-button matTooltip="Einrücken" [matTooltipShowDelay]="300"
(click)="indent()">
<mat-icon>format_indent_increase</mat-icon>
</button>
<button mat-icon-button matTooltip="Einrückung verringern" [matTooltipShowDelay]="300"
(click)="outdent()">
<mat-icon>format_indent_decrease</mat-icon>
</button>
</div>
<div fxLayout="row">
<div class="combo-button" fxLayout="row" [style.background-color]="editor.isActive('bulletList') ? 'lightgrey' : ''">
<button mat-icon-button matTooltip="Aufzählung" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('bulletList')"
(click)="toggleBulletList()">
<mat-icon>format_list_bulleted</mat-icon>
</button>
<mat-select [value]="editor.getAttributes('bulletList').listStyle"
(valueChange)="applyListStyle('bulletList', $event)">
<mat-option value="disc">disc</mat-option>
<mat-option value="circle">circle</mat-option>
<mat-option value="square">square</mat-option>
</mat-select>
</div>
<div class="combo-button" fxLayout="row" [style.background-color]="editor.isActive('orderedList') ? 'lightgrey' : ''">
<button mat-icon-button matTooltip="Aufzählung (nummeriert)" [matTooltipShowDelay]="300"
[class.active]="editor.isActive('orderedList')"
(click)="togleOrderedList()">
<mat-icon>format_list_numbered</mat-icon>
</button>
<mat-select [value]="editor.getAttributes('orderedList').listStyle"
(valueChange)="applyListStyle('orderedList', $event)">
<mat-option value="decimal">decimal</mat-option>
<mat-option value="lower-latin">lower-latin</mat-option>
<mat-option value="upper-latin">upper-latin</mat-option>
<mat-option value="lower-roman">lower-roman</mat-option>
<mat-option value="upper-roman">upper-roman</mat-option>
<mat-option value="lower-greek">lower-greek</mat-option>
</mat-select>
</div>
</div>
<button mat-icon-button class="special-chars-button" matTooltip="Sonderzeichen" [matTooltipShowDelay]="300"
[matMenuTriggerFor]="specialCharsMenu">
<mat-icon>emoji_symbols</mat-icon>
</button>
<mat-menu #specialCharsMenu="matMenu" yPosition="above">
<button mat-button (click)="insertSpecialChar('&nbsp;')"
[matTooltip]="'Geschütztes Leerzeichen'">&blank;</button>
<button mat-button (click)="insertSpecialChar('&female;')">&female;</button>
<button mat-button (click)="insertSpecialChar('&male;')">&male;</button>
<button mat-button (click)="insertSpecialChar('&micro;')">&micro;</button>
<br>
<button mat-button (click)="insertSpecialChar('&ccedil;')">&ccedil;</button>
<button mat-button (click)="insertSpecialChar('&Ccedil;')">&Ccedil;</button>
<button mat-button (click)="insertSpecialChar('&AElig;')">&AElig;</button>
<br>
<button mat-button (click)="insertSpecialChar('&lsaquo;')">&lsaquo;</button>
<button mat-button (click)="insertSpecialChar('&rsaquo;')">&rsaquo;</button>
<button mat-button (click)="insertSpecialChar('&laquo;')">&laquo;</button>
<button mat-button (click)="insertSpecialChar('&raquo;')">&raquo;</button>
<br>
<button mat-button (click)="insertSpecialChar('&cent;')">&cent;</button>
<button mat-button (click)="insertSpecialChar('&pound;')">&pound;</button>
<button mat-button (click)="insertSpecialChar('&yen;')">&yen;</button>
<br>
<button mat-button (click)="insertSpecialChar('&copy;')">&copy;</button>
<button mat-button (click)="insertSpecialChar('&reg;')">&reg;</button>
<button mat-button (click)="insertSpecialChar('&trade;')">&trade;</button>
<br>
<button mat-button (click)="insertSpecialChar('&le;')">&le;</button>
<button mat-button (click)="insertSpecialChar('&ge;')">&ge;</button>
<button mat-button (click)="insertSpecialChar('&fpartint;')">&fpartint;</button>
<button mat-button (click)="insertSpecialChar('&sum;')">&sum;</button>
<button mat-button (click)="insertSpecialChar('&isin;')">&isin;</button>
<button mat-button (click)="insertSpecialChar('&notin;')">&notin;</button>
<button mat-button (click)="insertSpecialChar('&radic;')">&radic;</button>
<button mat-button (click)="insertSpecialChar('&infin;')">&infin;</button>
<br>
<button mat-button (click)="insertSpecialChar('&spades;')">&spades;</button>
<button mat-button (click)="insertSpecialChar('&clubs;')">&clubs;</button>
<button mat-button (click)="insertSpecialChar('&hearts;')">&hearts;</button>
<button mat-button (click)="insertSpecialChar('&diams;')">&diams;</button>
</mat-menu>
<!-- <button mat-icon-button [matMenuTriggerFor]="optionsMenu">-->
<!-- <mat-icon>more_vert</mat-icon>-->
<!-- </button>-->
<!-- <mat-menu #optionsMenu="matMenu">-->
<!-- <mat-form-field>-->
<!-- <mat-label>Absatzabstand</mat-label>-->
<!-- <mat-select matTooltip="Achtung: Gilt nur für zukünftig angelegte Absätze" [matTooltipShowDelay]="300"-->
<!-- [value]="editor.getAttributes('paragraph').margin?.toString() || '0'"-->
<!-- (click)="$any($event).stopPropagation()" (valueChange)="applyParagraphStyle($event)">-->
<!-- <mat-option value="0">0px</mat-option>-->
<!-- <mat-option value="10">10px</mat-option>-->
<!-- <mat-option value="20">20px</mat-option>-->
<!-- </mat-select>-->
<!-- </mat-form-field>-->
<!-- </mat-menu>-->
</div>
</div>
<tiptap-editor [editor]="editor" [ngModel]="text" (ngModelChange)="textChange.emit($event)">
</tiptap-editor>
......@@ -28,6 +28,11 @@ export class RichTextEditorComponent implements AfterViewInit {
@Input() text!: string;
@Output() textChange = new EventEmitter<string>();
selectedFontColor = 'lightgrey';
selectedHighlightColor = 'lightgrey';
bulletListStyle: string = 'disc';
orderedListStyle: string = 'decimal';
editor = new Editor({
extensions: [StarterKit, Underline, Superscript, Subscript,
TextStyle, Color,
......@@ -85,12 +90,12 @@ export class RichTextEditorComponent implements AfterViewInit {
this.editor.commands.setFontSize(size);
}
applyColor(color: string): void {
this.editor.chain().focus().setColor(color).run();
applyFontColor(): void {
this.editor.chain().focus().setColor(this.selectedFontColor).run();
}
applyHighlight(color: string): void {
this.editor.chain().focus().toggleHighlight({ color: color }).run();
applyHighlightColor(): void {
this.editor.chain().focus().toggleHighlight({ color: this.selectedHighlightColor }).run();
}
alignText(direction: string): void {
......@@ -107,16 +112,20 @@ export class RichTextEditorComponent implements AfterViewInit {
toggleBulletList(): void {
this.editor.chain().toggleBulletList().focus().run();
this.editor.commands.setBulletListStyle(this.bulletListStyle);
}
togleOrderedList(): void {
this.editor.chain().toggleOrderedList().focus().run();
this.editor.commands.setBulletListStyle(this.orderedListStyle);
}
applyListStyle(listType: string, style: string): void {
if (listType === 'bulletList') {
this.bulletListStyle = style;
this.editor.commands.setBulletListStyle(style);
} else {
this.orderedListStyle = style;
this.editor.commands.setOrderedListStyle(style);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment