diff --git a/docs/src/content/docs/en/introduction.md b/docs/src/content/docs/en/introduction.md index 6b8160a9..96a3411b 100644 --- a/docs/src/content/docs/en/introduction.md +++ b/docs/src/content/docs/en/introduction.md @@ -57,12 +57,7 @@ Then in HTML ```html
- +
``` @@ -89,19 +84,14 @@ const jsonDoc = toDoc(html); ### Commands ```ts -this.editor.commands - .textColor('red') - .insertText('Hello world!') - .focus() - .scrollIntoView() - .exec(); +this.editor.commands.textColor('red').insertText('Hello world!').focus().scrollIntoView().exec(); ``` Run `exec` to apply the changes to the editor. ### Optional Configuration -You can specify locals to be used in the editor +You can specify locals and icons to be used in the editor ```ts NgxEditorModule.forRoot({ @@ -112,6 +102,9 @@ NgxEditorModule.forRoot({ underline: 'Underline', // ... }, + icons: { + bold: '', + }, }); ``` diff --git a/docs/src/content/docs/en/menu.md b/docs/src/content/docs/en/menu.md index 20c08dba..72d58784 100644 --- a/docs/src/content/docs/en/menu.md +++ b/docs/src/content/docs/en/menu.md @@ -45,12 +45,7 @@ export class AppComponent implements OnInit, OnDestroy { **component.html** ```html - - + ``` ## Custom Menu @@ -62,12 +57,7 @@ Note: The input is just a `TemplateRef`, the menu component will render whatever #### Editor ```html - - + @@ -172,3 +162,40 @@ OR - **editor** - (`Required`) editor instance - **autoPlace** - (`Optional`) positions automatically to the top or bottom based on the space available. `false` by default + +## Custom Icons in ngx-editor-menu + +By default ngx-editor add a list of google font icons, but have an option for replace with the icons you need. +Support svg/img/tags/etc, have the option for modify one or more icons. +You can specify the icons in the forRoot + +```ts +NgxEditorModule.forRoot({ + icons: { + bold: '', + }, +}); +``` + +The list of icon you can change is: + +- align_center +- align_justify +- align_left +- align_right +- bold +- bullet_list +- code +- color_fill +- format_clear +- horizontal_rule +- image +- italic +- link +- ordered_list +- quote +- strike +- text_color +- underline +- unlink +- path diff --git a/projects/ngx-editor/src/lib/Icons.ts b/projects/ngx-editor/src/lib/Icons.ts new file mode 100644 index 00000000..94c4184c --- /dev/null +++ b/projects/ngx-editor/src/lib/Icons.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/quotes */ +export const defaults: Record = { + // menu + align_center: ``, + align_justify: ``, + align_left: ``, + align_right: ``, + bold: ``, + bullet_list: ``, + code: ``, + color_fill: ``, + format_clear: ``, + horizontal_rule: ` + + +`, + image: ``, + italic: ``, + link: ``, + ordered_list: ``, + quote: ``, + strike: ``, + text_color: ``, + underline: ``, + unlink: ``, + path: ``, +}; + +export type IconsKeys = keyof typeof defaults; + +class Icons { + icons = defaults; + + constructor(newIcons: Partial> = {}) { + this.icons = { ...defaults, ...newIcons }; + } + + get = (key: string):string => { + return this.icons[key] ?? ''; + }; +} + +export default Icons; diff --git a/projects/ngx-editor/src/lib/editor-config.service.ts b/projects/ngx-editor/src/lib/editor-config.service.ts index ecdac69a..e667c154 100644 --- a/projects/ngx-editor/src/lib/editor-config.service.ts +++ b/projects/ngx-editor/src/lib/editor-config.service.ts @@ -5,4 +5,5 @@ import { Injectable } from '@angular/core'; }) export class NgxEditorServiceConfig { public locals = {}; + public icons = {}; } diff --git a/projects/ngx-editor/src/lib/editor.module.ts b/projects/ngx-editor/src/lib/editor.module.ts index a7548410..e3abf657 100644 --- a/projects/ngx-editor/src/lib/editor.module.ts +++ b/projects/ngx-editor/src/lib/editor.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { NgxEditorConfig } from './types'; import { defaults as defaultLocals } from './Locals'; +import { defaults as icons } from './Icons'; import { NgxEditorComponent } from './editor.component'; import { NgxEditorServiceConfig } from './editor-config.service'; @@ -17,6 +18,7 @@ export const NGX_EDITOR_CONFIG_TOKEN = new InjectionToken('NgxE const defaultConfig: NgxEditorConfig = { locals: defaultLocals, + icons, }; @NgModule({ diff --git a/projects/ngx-editor/src/lib/editor.service.ts b/projects/ngx-editor/src/lib/editor.service.ts index 013f3cf6..1694b534 100644 --- a/projects/ngx-editor/src/lib/editor.service.ts +++ b/projects/ngx-editor/src/lib/editor.service.ts @@ -3,6 +3,7 @@ import { Injectable, Optional } from '@angular/core'; import { NgxEditorConfig } from './types'; import Locals from './Locals'; import { NgxEditorServiceConfig } from './editor-config.service'; +import Icon from './icons/index'; @Injectable({ providedIn: 'root', @@ -17,10 +18,15 @@ export class NgxEditorService { get locals(): Locals { return new Locals(this.config.locals); } + + geticon(icon: string): string { + return this.config.icons[icon] ? this.config.icons[icon] : Icon.get(icon); + } } export const provideMyServiceOptions = (config?: NgxEditorConfig): NgxEditorServiceConfig => { return { locals: config.locals ?? {}, + icons: config.icons ?? {}, }; }; diff --git a/projects/ngx-editor/src/lib/icons.spec.ts b/projects/ngx-editor/src/lib/icons.spec.ts new file mode 100644 index 00000000..4dfc533c --- /dev/null +++ b/projects/ngx-editor/src/lib/icons.spec.ts @@ -0,0 +1,45 @@ +import { TestBed, ComponentFixture } from '@angular/core/testing'; + +import { NgxEditorModule } from 'ngx-editor'; +import Editor from './Editor'; +import { NgxEditorComponent } from './editor.component'; + +describe('NgxEditorModule', () => { + let component: NgxEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + TestBed.configureTestingModule({ + declarations: [ + NgxEditorComponent, + ], + imports: [ + NgxEditorModule.forRoot({ + icons: { + bold: '', + }, + }), + ], + }); + await TestBed.compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NgxEditorComponent); + component = fixture.componentInstance; + component.editor = new Editor(); + fixture.detectChanges(); + }); + + afterEach(() => { + component.editor.destroy(); + }); + + it('should create the editor component correctly', () => { + expect(component).toBeTruthy(); + }); + it('should create the icon correctly', () => { + const icon = document.getElementsByClassName('img-small'); + expect(icon).toBeTruthy(); + }); +}); diff --git a/projects/ngx-editor/src/lib/icons/index.ts b/projects/ngx-editor/src/lib/icons/index.ts index 5f15e136..4851ae1b 100644 --- a/projects/ngx-editor/src/lib/icons/index.ts +++ b/projects/ngx-editor/src/lib/icons/index.ts @@ -1,24 +1,30 @@ +/* eslint-disable @typescript-eslint/naming-convention */ // Icons source: https://material.io/ -import bold from './bold'; -import italic from './italic'; -import code from './code'; -import underline from './underline'; -import strike from './strike'; -import orderedList from './ordered_list'; -import bulletList from './bullet_list'; -import quote from './quote'; -import link from './link'; -import unlink from './unlink'; -import image from './image'; -import alignLeft from './align_left'; -import alignCenter from './align_center'; -import alignRight from './align_right'; -import alignJustify from './align_justify'; -import textColor from './text_color'; -import colorFill from './color_fill'; -import horizontalRule from './horizontal_rule'; -import formatClear from './format_clear'; +import Icons from '../Icons'; + +const ICON_LIST = new Icons(); + +const bold = ICON_LIST.get('bold'); +const italic = ICON_LIST.get('italic'); +const code = ICON_LIST.get('code'); +const underline = ICON_LIST.get('underline'); +const strike = ICON_LIST.get('strike'); +const ordered_list = ICON_LIST.get('ordered_list'); +const bullet_list = ICON_LIST.get('bullet_list'); +const quote = ICON_LIST.get('quote'); +const link = ICON_LIST.get('link'); +const unlink = ICON_LIST.get('unlink'); +const image = ICON_LIST.get('image'); +const align_left = ICON_LIST.get('align_left'); +const align_center = ICON_LIST.get('align_center'); +const align_right = ICON_LIST.get('align_right'); +const align_justify = ICON_LIST.get('align_justify'); +const text_color = ICON_LIST.get('text_color'); +const color_fill = ICON_LIST.get('color_fill'); +const horizontal_rule = ICON_LIST.get('horizontal_rule'); +const format_clear = ICON_LIST.get('format_clear'); +const path = ICON_LIST.get('path'); const DEFAULT_ICON_HEIGHT = 20; const DEFAULT_ICON_WIDTH = 20; @@ -30,36 +36,40 @@ const icons: Record = { code, underline, strike, - ordered_list: orderedList, - bullet_list: bulletList, + ordered_list, + bullet_list, blockquote: quote, link, unlink, image, - align_left: alignLeft, - align_center: alignCenter, - align_right: alignRight, - align_justify: alignJustify, - text_color: textColor, - color_fill: colorFill, - horizontal_rule: horizontalRule, - format_clear: formatClear, + align_left, + align_center, + align_right, + align_justify, + text_color, + color_fill, + horizontal_rule, + format_clear, + path, }; class Icon { static get(name: keyof typeof icons, fill = DEFAULT_ICON_FILL): string { - const path = icons[name] || ''; - return ` - - ${path} - - `; + const fullPath = icons[name]; + if (fullPath && (fullPath.includes(' + ${fullPath} + + `; + } + return fullPath; } } diff --git a/projects/ngx-editor/src/lib/modules/menu/bubble/bubble.component.ts b/projects/ngx-editor/src/lib/modules/menu/bubble/bubble.component.ts index 6532bee4..78bee1bc 100644 --- a/projects/ngx-editor/src/lib/modules/menu/bubble/bubble.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/bubble/bubble.component.ts @@ -4,7 +4,6 @@ import { EditorView } from 'prosemirror-view'; import { Subscription } from 'rxjs'; import Editor from '../../../Editor'; -import Icon from '../../../icons'; import { TBItems } from '../../../types'; import { SanitizeHtmlPipe } from '../../../pipes/sanitize/sanitize-html.pipe'; import { ToggleCommands } from '../MenuCommands'; @@ -50,8 +49,7 @@ export class BubbleComponent implements OnInit, OnDestroy { ]; getIcon(name: TBItems): SafeHtml { - const icon = Icon.get(name); - return this.sanitizeHTML.transform(icon); + return this.sanitizeHTML.transform(this.ngxeService.geticon(name)); } getTitle(name: string): string { diff --git a/projects/ngx-editor/src/lib/modules/menu/color-picker/color-picker.component.ts b/projects/ngx-editor/src/lib/modules/menu/color-picker/color-picker.component.ts index c10a3853..50533065 100644 --- a/projects/ngx-editor/src/lib/modules/menu/color-picker/color-picker.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/color-picker/color-picker.component.ts @@ -5,7 +5,7 @@ import { import { EditorView } from 'prosemirror-view'; import { Subscription } from 'rxjs'; -import Icon from '../../../icons'; +import Icon from '../../../icons/index'; import { NgxEditorService } from '../../../editor.service'; import { MenuService } from '../menu.service'; import { TextColor, TextBackgroundColor } from '../MenuCommands'; diff --git a/projects/ngx-editor/src/lib/modules/menu/image/image.component.ts b/projects/ngx-editor/src/lib/modules/menu/image/image.component.ts index 572f14c4..a8ac062d 100644 --- a/projects/ngx-editor/src/lib/modules/menu/image/image.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/image/image.component.ts @@ -9,7 +9,7 @@ import { Subscription } from 'rxjs'; import { NgxEditorService } from '../../../editor.service'; import { MenuService } from '../menu.service'; -import Icon from '../../../icons'; +import Icon from '../../../icons/index'; import { Image as ImageCommand } from '../MenuCommands'; @Component({ diff --git a/projects/ngx-editor/src/lib/modules/menu/insert-command/insert-command.component.ts b/projects/ngx-editor/src/lib/modules/menu/insert-command/insert-command.component.ts index 5b04e554..39ccc64a 100644 --- a/projects/ngx-editor/src/lib/modules/menu/insert-command/insert-command.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/insert-command/insert-command.component.ts @@ -2,11 +2,11 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { EditorView } from 'prosemirror-view'; import { Subscription } from 'rxjs'; -import Icon from '../../../icons'; import { InsertCommands } from '../MenuCommands'; import { NgxEditorService } from '../../../editor.service'; import { MenuService } from '../menu.service'; import { TBItems, ToolbarItem } from '../../../types'; +import icons from '../../../icons/index'; @Component({ selector: 'ngx-insert-command', @@ -54,7 +54,7 @@ export class InsertCommandComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.html = Icon.get(this.name); + this.html = icons.get(this.name); this.editorView = this.menuService.editor.view; diff --git a/projects/ngx-editor/src/lib/modules/menu/link/link.component.ts b/projects/ngx-editor/src/lib/modules/menu/link/link.component.ts index 5751f0df..87f11c6d 100644 --- a/projects/ngx-editor/src/lib/modules/menu/link/link.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/link/link.component.ts @@ -7,7 +7,7 @@ import { EditorView } from 'prosemirror-view'; import { Subscription } from 'rxjs'; import { NgxEditorService } from '../../../editor.service'; -import Icon from '../../../icons'; +import Icon from '../../../icons/index'; import { MenuService } from '../menu.service'; import { Link as LinkCommand } from '../MenuCommands'; diff --git a/projects/ngx-editor/src/lib/modules/menu/toggle-command/toggle-command.component.ts b/projects/ngx-editor/src/lib/modules/menu/toggle-command/toggle-command.component.ts index 834838fc..4c0c0ab3 100644 --- a/projects/ngx-editor/src/lib/modules/menu/toggle-command/toggle-command.component.ts +++ b/projects/ngx-editor/src/lib/modules/menu/toggle-command/toggle-command.component.ts @@ -2,7 +2,6 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { EditorView } from 'prosemirror-view'; import { Subscription } from 'rxjs'; -import Icon from '../../../icons'; import { ToggleCommands } from '../MenuCommands'; import { NgxEditorService } from '../../../editor.service'; import { MenuService } from '../menu.service'; @@ -56,7 +55,7 @@ export class ToggleCommandComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.html = Icon.get(this.name); + this.html = this.ngxeService.geticon(this.name); this.editorView = this.menuService.editor.view; diff --git a/projects/ngx-editor/src/lib/types.ts b/projects/ngx-editor/src/lib/types.ts index d59719d1..76de9665 100644 --- a/projects/ngx-editor/src/lib/types.ts +++ b/projects/ngx-editor/src/lib/types.ts @@ -1,6 +1,7 @@ import { EditorState } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; +import { IconsKeys } from './Icons'; import { LocalsKeys } from './Locals'; type TCR = { @@ -37,4 +38,5 @@ export type Toolbar = Array; export interface NgxEditorConfig { locals?: Partial>; + icons?: Partial>; }