Really promising project you have here! We've been looking to part ways with Summernote for a while now and this might just be it. Would you be open to having a way to configure the toolbar through props a bit like it's done in Summernote: http://summernote.org/deep-dive/#custom-toolbar-popover
Thanks!
Thanks @mathieumg: yeh it very close to what you have in summer-note. I already plan to work on super-script, sub-script and remove-style.
Exactly what other configurations are you looking for ?
A way to indicate what toolbars and what buttons to display, something similar to Summernote, approach could be different I imagine:
<Editor
toolbar={[
// [groupName, [list of button]]
['style', ['bold', 'italic', 'underline', 'clear']],
['font', ['strikethrough', 'superscript', 'subscript']],
['fontsize', ['fontsize']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['height', ['height']]
]}
/>
That looks very useful, I will do it - soon after 1.0. My priority first is to release a well documented 1.0.
Awesome, no hurry of course! :grin:
This change will be very useful I think and thus I plan to include it in 1.0.
My plan for it is that toolbar will be divided into groups (division will not be visible in UI):
It should be possible for user to:
@mathieumg , @theLordz: plz share your suggestion and feedbacks.
Prop to customize toolbar will be simple JS object. The object below list all the options but user needs to provide only those where he wants to override the defaults. Default value of visible will be true and inDropdown will be false. By default for icons current images (as shown in docs) will be used:
toolbarConfig = {
inline: {
visible: true,
inDropdown: false,
bold: { visible: true, icon: 'xxx.png', },
italic: { visible: true, icon: 'xxx.png', },
underline: { visible: true, icon: 'xxx.png', },
strikeThrough: { visible: true, icon: 'xxx.png', }
monospace: { visible: true, icon: 'xxx.png', }
},
blockType: { visible: true, },
fontSize: { visible: true, icon: 'xxx.png', }
fontFamily: { visible: true, }
list: {
visible: true,
inDropdown: true,
unordered: { visible: true, icon: 'xxx.png', },
ordered: { visible: true, icon: 'xxx.png', },
indent: { visible: true, icon: 'xxx.png', },
outdent: { visible: true, icon: 'xxx.png', }
},
textAlign: {
visible: true,
inDropdown: true,
left: { visible: true, icon: 'xxx.png', },
center: { visible: true, icon: 'xxx.png', },
right: { visible: true, icon: 'xxx.png', },
justify: { visible: true, icon: 'xxx.png', }
},
colorPicker: { visible: true, icon: 'xxx.png', }
link: {
visible: true,
inDropdown: true,
addLink: { visible: true, icon: 'xxx.png', },
removeLink: { visible: true, icon: 'xxx.png', },
},
image: {
visible: true,
icon: 'xxx.png',
fileUpload: true,
url: true,
},
history: {
visible: true,
inDropdown: true,
undo: { visible: true, icon: 'xxx.png', },
redo: { visible: true, icon: 'xxx.png', },
}
}
Very good start! :tada: What I liked about the array approach is that the developers can also reorder the groups and the buttons within each group however they see fit. For instance:
toolbar = [
['inline', [
'visible',
// omit strings instead of {visible: false}
{type: 'bold', icon: 'xxx.png'},
// etc.
],
'fontFamily', // different order than in yours
'blockType',
{type: 'link', inDropdown: true},
// etc.
],
I also kept toolbar as the prop name, it's pretty descriptive already as props are always a form of "config" when we think about it. Just my two cents, tell me what you think! :)
@mathieumg: I am not sure if I would prefer implicit ordering using array or rather explicit ordering using a field position. I think approach is different in using array toolbar is kind-of created by the array. But I am using these configurations to override the defaults.
I have created a new issue for ordering https://github.com/jpuri/react-draft-wysiwyg/issues/19, I actually want to release a stable 1.0 soon. But if time permits I will include it in 1.0.
Please share your opinions.
I am thinking it might actually be better to get rid of {visible: false} and show only those options which user asks for.
I think the approach I would prefer is:
Thus configuration will look like:
toolbar = {
inline: {
inDropdown: true,
options: {
bold: { icon: 'xxx.png' },
italic: { icon: 'xxx.png' },
underline: { icon: 'xxx.png' },
strikeThrough: { icon: 'xxx.png' },
monospace: { icon: 'xxx.png' }
}
},
blockType: { },
fontSize: { icon: 'xxx.png' }
fontFamily: { }
list: {
inDropdown: true,
options: {
unordered: { icon: 'xxx.png' },
ordered: { icon: 'xxx.png' },
indent: { icon: 'xxx.png' },
outdent: { icon: 'xxx.png' }
}
},
textAlign: {
inDropdown: true,
options: {
left: { icon: 'xxx.png' },
center: { icon: 'xxx.png' },
right: { icon: 'xxx.png' },
justify: { icon: 'xxx.png' }
}
},
colorPicker: { icon: 'xxx.png' }
link: {
inDropdown: true,
options: {
addLink: { icon: 'xxx.png' },
removeLink: { icon: 'xxx.png' },
}
},
image: {
icon: 'xxx.png',
fileUpload: true,
url: true,
},
history: {
inDropdown: true,
options: {
undo: { icon: 'xxx.png' },
redo: { icon: 'xxx.png' },
}
}
}
I also like the idea of using toolbar rather than toolbarConfig. I also see some advantages of using array but I think simple object gives more flexibility. later I will add more configuration parameters like position for ordering, etc.
Thanks a ton of your useful input - please share your feedbacks.
Finally I have arrived on this configuration:
https://github.com/jpuri/react-draft-wysiwyg/blob/toolbar_customization/js/src/config/defaultToolbar.js
It looks much generic and also extensible to me. It will be immutable data-structure and there will be deep merge with what user provides. DeepMerge will merge only objects and not arrays.
Cool! So options can be used to change the order if need be. Looks good!
I actually want to avoid implicit ordering based on position, later I plan to add additional fields position, ... like icon right now.
Ordering will not be supported right now.
@mathieumg: basic support for customizing toolbar is now in master branch. I will work to add more options to it later.
Thanks a lot for your nice suggestions 馃憤
Awesome, thanks! Did you want me to close this issue?
I think it can be closed. I added any other issue for allowing ordering of options in toolbar.
Please share more suggestions for improving the editor.
At this moment i can't create own toolbar with custom blocks, for example it will cause error:
{
options: ['textIndent', 'list'],
textIndent: {
inDropdown: false,
className: undefined,
component: undefined,
dropdownClassName: undefined,
options: ['indent', 'outdent'],
indent: { className: undefined },
outdent: { className: undefined },
},
list: {
inDropdown: false,
className: undefined,
component: undefined,
dropdownClassName: undefined,
options: ['unordered', 'ordered'],
unordered: { className: undefined },
ordered: { className: undefined },
},
}
because 'textIndent' not supported. How can we make fully custom toolbar like this:

?
@AndreyMiloserdov : can you plz share exactly what error / result do you get for above code snippet.

Another problem in src/controls/TextAlign/Component/index.js
<div className={classNames('rdw-text-align-wrapper', className)} aria-label="rdw-textalign-control">
no any currentState in the className property: can't set custom icon for selected style, only default image as icon, no any css possibility for this
Same for the list buttons.
@jpuri how does one disable something like fontFamily in the current configuration model?
edit: nevermind, can explicitly include them under toolbar.options array. thanks!
Yes @ericnkatz , toolbar property can be used to remove toolbar options.
First of all, really love the library!
@jpuri what if we want to show "B(bold)" "I(italics)" and the rest of the inline functionalities in a dropdown instead of having the whole inline as dropdown
@jpuri also, why can't we customise the drop-down icon for toolbar icons it seems to take the first option of the subarray (i.e) If I wan to but inline in a drop-down shouldn't I have an option to add an icon for the drop-down instead of using "Bold" as the icon just because it is the first function
@jpuri Can we insert link to custom toolbar values like we do in summernote?
ui.dropdown({
//items: ['thing', 'thing2'],
contents: "<li><a href='#' data-name='test' data-url='www.example.com'>example</a></li>",
callback: function (items) {
$(items).find('li a').on('click', function(){
context.invoke("editor.createLink", {text: $(this).data('name'), url: $(this).data('url'), isNewWindow: true });
})
}
})
Most helpful comment
@mathieumg: basic support for customizing toolbar is now in master branch. I will work to add more options to it later.
Thanks a lot for your nice suggestions 馃憤