Creating a WYSIWYG Editor with React

Post on 07-Aug-2015

1.273 views 10 download

Tags:

Transcript of Creating a WYSIWYG Editor with React

Creating a WYSIWYG editor with React

@ipeychev

(or lets see how deep the rabbit hole goes)

ReactA JavaScript library for building user interfaces

Why React?

Why React?

React allows you to concentrate on the UI of your application

Why React?

Instead to focus on implementation details, fighting with the DOM and resolving performance issues

React in a nutshell

React in a nutshell

Library, not a framework

Implements one-way reactive data

flow

Blazingly fast

React in a nutshell

Virtual DOM

JSX

JavaScript syntax extension (JSX)

React in a nutshell

Native applications

Isomorphic applications

Client-side applications

Creating UI with React

Main UI

Nested Components

Data flow

Creating a component

Render the component

Update state

But... Isn't that slow?!

Performance

And rendering is fast

Virtual DOM rulez

Performance

Components

Component are state machines

You render initially the components based on the properties

Components

Then you change their state and they will be automatically re-rendered

React renders nested components with deep hierarchy

Without compromising the performance

Components performance

(thanks to the Virtual DOM)

Components example

} Main component with nested components

Render part}

Reusable code

1 var HelloWorld = React.createClass({ 2 mixins: [MyMixin, YourMixin], 3 4 render: function() { 5 var a = this.getA(); 6 var b = this.getB(); 7 8 return (a + b); 9 }

Mixins

A higher-order component is a function that takes an existing component and returns another component that wraps it

Higher-order components

Properties

Unconditionally configure your components

Which will help you to debug and test them

Properties are immutable, they are owned by the parent element

Properties

Properties

Properties

State

State

Change your components based on user actions or data from server

When the state is updated, the component re-renders itself.

State should be considered as private data

Properties vs State

Properties are initialized when components are created

State is only seen on the inside of components definitions

Properties vs State

Events

Attaching events

<button onClick={this._handleClick} ...

Attach them in DOM 0 way:

Events are not attached to the element itself

React is listening for all events at the top level using a single event listener

When an event occurs, React dispatches it accordingly

Events delegation

React autobinds the method to its component instance

Events autobinding

There is no need to write .bind(this):

<button onClick={this._handleClick .bind(this)}

Let's see how deep the rabbit hole goes

AlloyEditor

http://alloyeditor.com

An Open Source

WYSIWYG editor

built with React

AlloyEditor design goals

The developer should be able to replace the UI entirely

!It should be accessible"

Toolbars should appear when needed and where needed

#

The UI should be separated from the core$

The UI should be easy to be styled%

AlloyEditor design goals

It should work on all browsers

AlloyEditor architecture

UI core Plugins, low level modules

Engine CKEditor Core

Toolbar Toolbar Toolbar

Button Button } AlloyEditor UI

based on React + our own code around it

AlloyEditor architecture

Code around React

React provides the rendering part only

That is not enough

Core, Attributes and Events

Basic stuff is needed, for example:

OOP

Types validation

Configurations

Custom Events

Instantiating AlloyEditor

Instantiating AlloyEditor

Many editors can be instantiated on one page

1 <script> 2 var editor1 = AlloyEditor.editable('description'); 3 var editor2 = AlloyEditor.editable('editable'); 4 </script>

Selections

Selections

Currently there are four types:

Image Text Table Link

Selections

Exposed in AlloyEditor.Selections

You can add your own

Buttons reordering

Buttons reordering

1 <script> 2 AlloyEditor.Selections[2].buttons = ['bold', 'italic', 'underline', 'link', 'twitter']; 3 </script>

AlloyEditor.Selections[2] is the text selection.

Instead of hardcoding it, you can also retrieve it by enumerating it inside the array

Buttons reordering

1 <script> 2 AlloyEditor.Selections[2].buttons = ['italic', 'bold', 'underline', 'link', 'twitter']; 3 </script>

AlloyEditor.Selections[2] is the text selection.

Instead of hardcoding it, you can also retrieve it by enumerating it inside the array

Buttons reordering

1 <script> 2 _.find(AlloyEditor.Selections, function(selection) { 3 var found = selection.name === 'text'; 4 5 if (found) { 6 selection.buttons = ['bold', 'italic', 'underline', 'link', 'twitter']; 7 } 8 9 return found; 10 }); 11 </script>

Buttons reordering

1 <script> 2 _.find(AlloyEditor.Selections, function(selection) { 3 var found = selection.name === 'text'; 4 5 if (found) { 6 selection.buttons = ['italic', 'bold', 'underline', 'link', 'twitter']; 7 } 8 9 return found; 10 }); 11 </script>

Adding new buttons

A button is just a ReactJS module

1 var ButtonH4 = React.createClass({ 2 mixins: [AlloyEditor.ButtonStyle, AlloyEditor.ButtonStateClasses, AlloyEditor.ButtonActionStyle], 3 4 statics: { 5 key: 'h4' 6 }, 7 8 getDefaultProps: function() { 9 return { 10 style: { 11 element: 'h4' 12 } 13 }; 14 }, 15 16 render: function() { 17 var cssClass = 'alloy-editor-button ' + this.getStateClasses(); 18 19 return ( 20 <button className={cssClass} data-type="button-h4" onClick={this.applyStyle}tabIndex={this.props.tabIndex}> 21 <span className="alloy-editor-icon-h4"></span> 22 </button> 23 ); 24 } 25 }); 26 27 AlloyEditor.Buttons[ButtonH4.key] = AlloyEditor.ButtonH4 = ButtonH4;

Adding a new button

1 <script> 2 _.find(AlloyEditor.Selections, function(selection) { 3 var found = selection.name === 'text'; 4 5 if (found) { 6 selection.buttons = ['h4', 'italic', 'bold', 'underline', 'link']; 7 } 8 9 return found; 10 }); 11 </script>

Skins!

Wait, there is even more!

More stuff available!

Drag&Drop images from Desktop to the editor&

Auto link creation&

Placeholder plugin&

Your own toolbars and buttons!&

Roadmap

Roadmap

Mobile support♥

Implement more buttons♥

Improve accessibility♥

Any ideas?

Demo time

Thanks!

Questions?

ipeychev