Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the correct way to modify modules and icons? #370

Closed
ArsalanSavand opened this issue Apr 11, 2019 · 14 comments
Closed

What is the correct way to modify modules and icons? #370

ArsalanSavand opened this issue Apr 11, 2019 · 14 comments

Comments

@ArsalanSavand
Copy link

Hello, I have used ng-quill on an Angularjs project and I was able to modify modules and icons and even add new handlers and buttons.

I'm now on an Angular 7 project, I was wondering how can I modify let's say icons. Do I have to use quilljs for it which is Javascript, or is there a way to modify icons in ngx-quill ?

This is what I wrote in a component called WriteComponent and I'm not sure if It's the correct way.

import { Component, OnInit } from '@angular/core';
const Quill = require('quill');

const icons = Quill.import('ui/icons');


@Component({
  selector: 'app-write',
  templateUrl: './write.component.html',
  styleUrls: ['./write.component.scss'],
})
export class WriteComponent implements OnInit {

  constructor() {
    icons['bold'] = '<ion-icon name="add"></ion-icon>';
  }

  ngOnInit() {
  }

}

I need Quill to add new handlers, modules, icons and registering them and so on.
This code works just fine, but I'm still not sure if I should do such code in Angular 7.

@ArsalanSavand ArsalanSavand changed the title What is the correct way to modify modules and icons. What is the correct way to modify modules and icons? Apr 11, 2019
@KillerCodeMonkey
Copy link
Owner

eehm i do not know how you have did this with ng-quill. But in generel you should create a quilljs theme:

https://quilljs.com/docs/themes/#themes
or override the existing style with css or build a custom toolbar:

<quill-editor>
  <div quill-editor-toolbar>
    <span class="ql-formats">
      <button class="ql-bold" [title]="'Bold'"></button>
    </span>
    <span class="ql-formats">
      <select class="ql-align" [title]="'Aligment'">
        <option selected></option>
        <option value="center"></option>
        <option value="right"></option>
        <option value="justify"></option>
      </select>
      <select class="ql-align" [title]="'Aligment2'">
        <option selected></option>
        <option value="center"></option>
        <option value="right"></option>
        <option value="justify"></option>
      </select>
    </span>
  </div>
</quill-editor>

@ArsalanSavand
Copy link
Author

I can override the existing styles or build a custom toolbar. The problem is if I add an icon inside a button element, it will be override by quill.

My question is not custom toolbar. I just want to know how can I for example import something from Quill in Angular 7.

This is how I did it in Angularjs:

import Quill from "quill";

const BlockEmbed = Quill.import("blots/block/embed");
const Clipboard = Quill.import("modules/clipboard");
const icons = Quill.import("ui/icons");

@KillerCodeMonkey
Copy link
Owner

This should work the same with angular >2

Install the the quill typings and go an. in my demo repo i am using Quill.import to change fonts or change the default block element.

I never changed icons, but if this worked before i see no problem, why this should not work.

@ArsalanSavand
Copy link
Author

Alright got it. Thanks for the quick response 👍

@srinivasthutika
Copy link

Arsalan,
do you have your working version of angular7 project where you changed icon.

@srinivasthutika
Copy link

Can you give working example on importing quill icons. I am looking to import table icons from assets.
This is how i am doing
private getInsertTableButton() {
const myButton = new QuillToolbarButton({
icon: 'TI'
});
const table = this.table;
myButton.onClick = function(quill) {
table.insertTable(2, 2);
};
myButton.attach(this.quill);
}

I am using text now. How can i add icon for the same. I can see table SVG icon in quill/assets/icons

@ArsalanSavand
Copy link
Author

ArsalanSavand commented Feb 29, 2020

@srinivasthutika What icons are you using? Angular FontAwesome?

If yes, then I wrote a .ts file to change QuillJs's built-in icons to FontAwesome icons:

import { CustomIcon } from '@app/interfaces/custom-icon';
import { IconDefinition } from '@fortawesome/fontawesome-common-types';
import { faYoutube } from '@fortawesome/free-brands-svg-icons';
import { faAlignCenter } from '@fortawesome/free-solid-svg-icons/faAlignCenter';
import { faAlignJustify } from '@fortawesome/free-solid-svg-icons/faAlignJustify';
import { faAlignLeft } from '@fortawesome/free-solid-svg-icons/faAlignLeft';
import { faAlignRight } from '@fortawesome/free-solid-svg-icons/faAlignRight';
import { faBan } from '@fortawesome/free-solid-svg-icons/faBan';
import { faBold } from '@fortawesome/free-solid-svg-icons/faBold';
import { faCode } from '@fortawesome/free-solid-svg-icons/faCode';
import { faImage } from '@fortawesome/free-solid-svg-icons/faImage';
import { faItalic } from '@fortawesome/free-solid-svg-icons/faItalic';
import { faLink } from '@fortawesome/free-solid-svg-icons/faLink';
import { faListUl } from '@fortawesome/free-solid-svg-icons/faListUl';
import { faMinus } from '@fortawesome/free-solid-svg-icons/faMinus';
import { faParagraph } from '@fortawesome/free-solid-svg-icons/faParagraph';
import { faQuoteRight } from '@fortawesome/free-solid-svg-icons/faQuoteRight';
import { faStrikethrough } from '@fortawesome/free-solid-svg-icons/faStrikethrough';
import { faUnderline } from '@fortawesome/free-solid-svg-icons/faUnderline';
import Quill, { StringMap } from 'quill';

/**
 * Quill icons
 */
const Icons: StringMap = Quill.import('ui/icons');

/**
 * List of icons to change
 */
const customIcons: CustomIcon[] = [{
  default: 'bold',
  new: faBold,
}, {
  default: 'italic',
  new: faItalic,
}, {
  default: 'underline',
  new: faUnderline,
}, {
  default: 'strike',
  new: faStrikethrough,
}, {
  default: 'blockquote',
  new: faQuoteRight,
}, {
  default: 'link',
  new: faLink,
}, {
  default: 'code-block',
  new: faCode,
}, {
  default: 'divider',
  new: faMinus,
}, {
  default: 'image',
  new: faImage,
}, {
  default: 'video',
  new: faYoutube,
}, {
  default: 'clean',
  new: faBan,
}];

/**
 * Convert given icon to SVG element which contains a path element
 *
 * @param icon FortAwesome icon
 * @param classList List of classes to attach to SVG element
 *
 * @see IconDefinition
 * @link https://github.com/FortAwesome/angular-fontawesome/blob/master/docs/usage.md
 *
 * @returns SVG element based on given icon
 */
export function iconToSVGElement(icon: IconDefinition, classList?: string): SVGSVGElement {
  /**
   * Create SVG element
   */
  const node: SVGSVGElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  /**
   * Add classes
   */
  node.classList.add('svg-inline--fa', 'fa-fw', `${icon.prefix}-${icon.iconName}`);
  if (classList) {
    node.classList.add(classList);
  }
  /**
   * Set node viewBox
   */
  node.viewBox.baseVal.width = icon.icon[0];
  node.viewBox.baseVal.height = icon.icon[1];
  /**
   * Create Path element
   */
  const path: SVGPathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  /**
   * Set `fill` attribute's value to `currentColor` so it can adjustable
   */
  path.setAttributeNS(null, 'fill', 'currentColor');
  /**
   * Set `d` attribute's value to given icon's path commands
   *
   * 'd' is a string containing a series of path commands that define the path to be drawn
   */
  path.setAttributeNS(null, 'd', icon.icon[icon.icon.length - 1] as string);
  /**
   * Append {@link path} to {@link node} as a child
   */
  node.appendChild<SVGPathElement>(path);
  /**
   * Return node
   */
  return node;
}

/**
 * Loop into {@link customIcons} and change default icons
 */
customIcons.forEach((icon: CustomIcon): void => {
  Icons[icon.default] = iconToSVGElement(icon.new).outerHTML;
});

Icons.list.bullet = iconToSVGElement(faListUl).outerHTML;
Icons.direction[''] = iconToSVGElement(faParagraph).outerHTML;
Icons.direction.rtl = iconToSVGElement(faParagraph, 'fa-flip-horizontal').outerHTML;
Icons.align[''] = iconToSVGElement(faAlignLeft).outerHTML;
Icons.align.center = iconToSVGElement(faAlignCenter).outerHTML;
Icons.align.right = iconToSVGElement(faAlignRight).outerHTML;
Icons.align.justify = iconToSVGElement(faAlignJustify).outerHTML;

Quill.register(Icons, true);

@ArsalanSavand ArsalanSavand reopened this Feb 29, 2020
@KillerCodeMonkey
Copy link
Owner

@ArsalanSavand why reopening this issue?

@ArsalanSavand
Copy link
Author

ArsalanSavand commented Feb 29, 2020

@KillerCodeMonkey Sorry my bad, I will just comment. I will close it now.

@KillerCodeMonkey
Copy link
Owner

in general this is done like for plain quilljs.
So just search the issues in the quilljs repo.
slab/quill#1099 (comment)

@karlosmrez
Copy link

How can i overwrite the dropdown icon? This icon is not into icons.js.

@KillerCodeMonkey
Copy link
Owner

KillerCodeMonkey commented Mar 27, 2020 via email

@konlanx
Copy link

konlanx commented Dec 16, 2021

Hello!

Maybe someone can point me in the right direction as I am having problems with using quill and ngx-quill in a library and then including that library and it seems to be related to the icons, as the error-message indicates that.

Recently these projects went from Angular 9 to Angular 11. In Angular 9 we had no issues with the icons not being available. The same constellation of projects built successfully using Angular 9. Without quill the projects built successfully using Angular 11. But with quill and Angular 11 I run into issues.

I have a library that includes quill and ngx-quill. In the library we modify the icons like this:

ngOnInit(): void {
    const icons: StringMap = Quill.import('ui/icons');
    icons.bold = '<i class="icon icon-bold" aria-hidden="true"></i>';
    icons.italic = '<i class="icon icon-italic" aria-hidden="true"></i>';
...
}

When using for example storybook I can just run the library and all icons work just fine. But when I include the library in a different project I get a compilation error:

PS C:\project> ng build some-project
Building Angular Package

------------------------------------------------------------------------------
Building entry point '@some-org/some-project'
------------------------------------------------------------------------------
× Compiling TypeScript sources through NGC
ERROR: The target entry-point "@some-org/some-lib" has missing dependencies:
 - ui/icons

An unhandled exception occurred: The target entry-point "@some-org/some-lib" has missing dependencies:
 - ui/icons

See "C:\angular-errors.log" for further details.

I tried setting quill (and related libs) as whitelistedNonPeerDependencies for the library in the hopes of making the files available this way, but it did not succeed:

package.json

  "dependencies": {
    "ngx-quill": "14.3.0",
    "quill": "1.3.7",
    "quill-blot-formatter": "1.0.5",
    "quill-drag-and-drop-module": "0.3.0"
  },
  "peerDependencies": {
    "@angular/common": "11.2.14",
    "@angular/core": "11.2.14",
    "@angular/animations": "11.2.14",

ng-package.json

  "allowedNonPeerDependencies": [
    "ngx-quill",
    "quill",
    "quill-blot-formatter",
    "quill-drag-and-drop-module"
  ]

This did not help and did not resolve the issue. I also tried including quill explicitely in all projects, but the error persists.

I could verify that quill is available in node_modules and does in fact contain a folder ui and a file icons.js. This was the case for all projects, including the project that reports the missing dependency.

Am I missing something here? I am unable to pinpoint why the ui/icons would be a missing dependency.

Thanks in advance!

@konlanx
Copy link

konlanx commented Dec 16, 2021

The current workaround is to remove the Quill.import('ui/icons')-part and call it in the root-project that imports all libraries. This isn't optimal since we wanted to hide this code, but it works and gets rid of the error.

I was able to make the code short by keeping the logic in the library. My application now has this code:

app.component.ts

import {LibraryComponent} from '@some-org/some-lib';

ngOnInit() {
  // Initialize quill
  const icons: StringMap = Quill.import('ui/icons');
  LibraryComponent.initEditor(icons);
...
}

And in the library I have the following function:

some-component.component.ts

  public static initEditor(icons: StringMap): void {
    icons.bold = '<i class="icon icon-bold" aria-hidden="true"></i>';
    icons.italic = '<i class="icon icon-italic" aria-hidden="true"></i>';
...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants