GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
BSD 3-Clause "New" or "Revised" License
22.37k stars 4.05k forks source link

Adding toolbar items #204

Closed Pisikoll closed 7 years ago

Pisikoll commented 7 years ago

Hey

capture

I would like to add new buttons to this section, but I can't find anything from wiki. Also is there any way to listen when element is selected?

Thanks

artf commented 7 years ago

Hi @Pisikoll at the moment I haven't yet documented components toolbar but it's just an array of objects containing 2 keys: attributes and command which indicates the command to execute. For instance, the default component would be like this:

defaults: {
  // other model properties
  toolbar: [{
    attributes: {class: 'fa fa-arrows'},
    command: 'tlb-move',
  },{
    attributes: {class: 'fa fa-clone'},
    command: 'tlb-clone',
  },{
    ...
  }],
}

If you want to know when one of those buttons is executed you can listen to command events

editor.on('run:tlb-clone', () => {});
kukreja38 commented 6 years ago

hi @artf can we add button and like star icon in right toolbox? Thanks!

umerrinayat commented 5 years ago

Hi @artf I'm trying to add a new element in blue toolbar. e.g. A link icon. Is there any way I can update the toolbar in grapesjs initialization? I'm currently using grapesjs in react based project. Thanks

labmux commented 5 years ago

@kukreja38 @umerrinayat @Pisikoll Hey guys, so the way I added my own toolbar element was to override the default toolbar with my own as so:

component.set({
                    toolbar: [
                        // these are the default toolbar elements
                        {
                            attributes: {class: 'fa fa-arrow-up'},
                            command: 'select-parent'
                        },
                        {
                            attributes: {class: 'fa fa-arrows'},
                            command: 'tlb-move'
                        },
                        {
                            attributes: {class: 'fa fa-clone'},
                            command: 'tlb-clone',
                        },
                        {
                            attributes: {class: 'fa fa-trash'},
                            command: 'tlb-delete'
                        },
                        // this is my new toolbar element with my custom command
                        {
                            attributes: {class: 'fa fa-arrows-alt'},
                            command: 'tlb-fill'
                        }
                    ]
                });

Hope this helped

update: I really dont know why it didnt indent my code, sorry about that

Elvincth commented 4 years ago

@kukreja38 @umerrinayat @Pisikoll Hey guys, so the way I added my own toolbar element was to override the default toolbar with my own as so:

component.set({ toolbar: [ // these are the default toolbar elements { attributes: {class: 'fa fa-arrow-up'}, command: 'select-parent' }, { attributes: {class: 'fa fa-arrows'}, command: 'tlb-move' }, { attributes: {class: 'fa fa-clone'}, command: 'tlb-clone', }, { attributes: {class: 'fa fa-trash'}, command: 'tlb-delete' }, // this is my new toolbar element with my custom command { attributes: {class: 'fa fa-arrows-alt'}, command: 'tlb-fill' } ] });

Hope this helped

update: I really dont know why it didnt indent my code, sorry about that

Hello , I would like to ask what is the variable "component" excatly , editor.DomComponents? Cause, I tried it dosen't work thx.

umerrinayat commented 4 years ago

Hey @Elvincth Yes you have to use editor.DomComponents to get specific type and change it toolbar. Here is my code where I'm adding a link icon in toolbar when use click on anchor tag.


let linkCommandId = 'tlb-link-editor-modal'; // Id to use to create the button and anchor tag editor command
let toolbarIcon = `<i class="fas fa-paperclip"></i>`; // Icon used in the component toolbar

var linkType = editor.DomComponents.getType('link');
const linkTypeModel = editor.DomComponents.getType('link').model;

editor.DomComponents.addType('link', {
    model: {
        initToolbar() {
            linkTypeModel.prototype.initToolbar.apply(this, arguments);
            const tb = this.get('toolbar');
            const tbExists = tb.some(item => item.command === linkCommandId);

            // Add link icon in case user click on anchor tag
            if (!tbExists) {
                tb.unshift({
                    command: linkCommandId,
                    label: toolbarIcon,
                });
                this.set('toolbar', tb);
            }
        }
    },
    // Double click on link open link editor
    view: linkType.view.extend({
        events: {
            "dblclick": "editLink"
        },
        editLink: function (e) {
            e.stopImmediatePropagation(); // prevent the RTE from opening
            editor.runCommand(linkCommandId, {});
        }
    })
});

Screenshot 2020-02-03 at 2 15 10 PM

Elvincth commented 4 years ago

Hey @Elvincth Yes you have to use editor.DomComponents to get specific type and change it toolbar. Here is my code where I'm adding a link icon in toolbar when use click on anchor tag.


let linkCommandId = 'tlb-link-editor-modal'; // Id to use to create the button and anchor tag editor command
let toolbarIcon = `<i class="fas fa-paperclip"></i>`; // Icon used in the component toolbar

var linkType = editor.DomComponents.getType('link');
const linkTypeModel = editor.DomComponents.getType('link').model;

editor.DomComponents.addType('link', {
  model: {
      initToolbar() {
          linkTypeModel.prototype.initToolbar.apply(this, arguments);
          const tb = this.get('toolbar');
          const tbExists = tb.some(item => item.command === linkCommandId);

          // Add link icon in case user click on anchor tag
          if (!tbExists) {
              tb.unshift({
                  command: linkCommandId,
                  label: toolbarIcon,
              });
              this.set('toolbar', tb);
          }
      }
  },
  // Double click on link open link editor
  view: linkType.view.extend({
      events: {
          "dblclick": "editLink"
      },
      editLink: function (e) {
          e.stopImmediatePropagation(); // prevent the RTE from opening
          editor.runCommand(linkCommandId, {});
      }
  })
});

Screenshot 2020-02-03 at 2 15 10 PM

Got it thankas a lot for your reply! It helped me alot 👍

devtechk commented 3 years ago

Hi guys, what if I'd like to edit only an existing toolbar's icon class name? I'm using another fontawesome version and i need to change some classes there. How can I do, I'm trying to figure out but I can't now... Thank you!

devtechk commented 3 years ago

Really simple this simple trick solved for me, just write/overwrite new css rules in your style css/scss file in my case I needed to replace some icons (old fontawasome) .fa-arrows and .fa-trash-o (New fontawasome) .fa-arrows-alt and .fa-trash

.fa-arrows:before {
    content: "\F0B2";
}
.fa-trash-o:before {
    content: "\F1F8";
}
mingxin-yang commented 2 years ago

how to add some element to all components @artf

wdison commented 2 years ago

@mingxin-yang

I use a code like this

export default (editor, opts = {}) => {
  const dc = editor.DomComponents;
  const id = 'custom-id';
  const htmlLabel = `<svg viewBox="0 0 24 24">
                      <path d="M14.6 16.6l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4m-5.2 0L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4z"></path>
                    </svg>`;

  dc.getTypes().forEach(elType => {
    let {model:oldModel, view:oldView} = elType;
    console.log(JSON.stringify(elType));
    dc.addType(elType.id, {
      model: oldModel.extend({
        initToolbar() {
          oldModel.prototype.initToolbar.apply(this, arguments);
          const toolbar = this.get('toolbar');

          if (!toolbar.filter(tlb => tlb.id === id ).length) {
            toolbar.unshift({
              id,
              command: function(){alert("Custom toolbar");},
              label: htmlLabel
            });
            this.set('toolbar', toolbar);
          }
        }
      }),
      view: oldView
    });
  });
}

image

AgnRakul commented 1 year ago

Its Possible to add Text Instead of Icons

chaegumi commented 1 year ago

good job!

        model: {
            initToolbar() {
                defaultModel.prototype.initToolbar.apply(this, arguments)
                const tb = this.get('toolbar')
                const tbExists = tb.some(item => item.command === 'tlb-add-container');

                if (!tbExists) {
                    tb.unshift({
                        command: 'tlb-add-container',
                        attributes: { class: 'fa fa-plus', title: 'Add Container' }
                    });

                    editor.Commands.add('tlb-add-container', editor => {
                        alert('this is my command')
                    })

                    this.set('toolbar', tb);
                }
            },
            defaults: {
amitkprimo commented 1 year ago

Hey @Elvincth Yes you have to use editor.DomComponents to get specific type and change it toolbar. Here is my code where I'm adding a link icon in toolbar when use click on anchor tag.


let linkCommandId = 'tlb-link-editor-modal'; // Id to use to create the button and anchor tag editor command
let toolbarIcon = `<i class="fas fa-paperclip"></i>`; // Icon used in the component toolbar

var linkType = editor.DomComponents.getType('link');
const linkTypeModel = editor.DomComponents.getType('link').model;

editor.DomComponents.addType('link', {
  model: {
      initToolbar() {
          linkTypeModel.prototype.initToolbar.apply(this, arguments);
          const tb = this.get('toolbar');
          const tbExists = tb.some(item => item.command === linkCommandId);

          // Add link icon in case user click on anchor tag
          if (!tbExists) {
              tb.unshift({
                  command: linkCommandId,
                  label: toolbarIcon,
              });
              this.set('toolbar', tb);
          }
      }
  },
  // Double click on link open link editor
  view: linkType.view.extend({
      events: {
          "dblclick": "editLink"
      },
      editLink: function (e) {
          e.stopImmediatePropagation(); // prevent the RTE from opening
          editor.runCommand(linkCommandId, {});
      }
  })
});

Screenshot 2020-02-03 at 2 15 10 PM

That's great but when we write FOR TEXT

This is a react code. when i run this code then show always/often this err

ERRR

Cannot read properties of undefined (reading 'parseHtml') TypeError: Cannot read properties of undefined (reading 'parseHtml') at n.parseString (http://localhost:3000/static/js/bundle.js:20076:26) at n.resetFromString (http://localhost:3000/static/js/bundle.js:20013:22) at o. (http://localhost:3000/static/js/bundle.js:23040:52) at http://localhost:3000/static/js/bundle.js:22913:23 at Object.next (http://localhost:3000/static/js/bundle.js:22924:14) at s (http://localhost:3000/static/js/bundle.js:22829:19)

import React, { useEffect, useRef, useState } from "react"; import grapesjs from "grapesjs"; import "grapesjs/dist/css/grapes.min.css"; import "grapesjs-blocks-basic";

// import pdfjsLib from "pdfjs-dist";+

const WebBuilder = () => { const editorRef = useRef(null); let editor; const [showPopup, setShowPopup] = useState(false); const [customCodeContent, setCustomCodeContent] = useState("");

useEffect(() => { editor = grapesjs.init({ container: editorRef.current, // Other GrapeJS options and plugins });

editor.DomComponents.addType("text", { model: { initToolbar() { // Get the default toolbar items const defaultToolbar = this.get("toolbar") || [];

    // Add the custom button to the toolbar
    const customButton = {
      attributes: { class: "fa fa-custom-icon" },
      command: "custom-text-action",
    };
    defaultToolbar.push(customButton);

    this.set("toolbar", defaultToolbar);
  },
},

});