diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index dbc72e320..774deebb3 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -63,6 +63,7 @@ module.exports = {
['/api/block_manager', 'Block Manager'],
['/api/commands', 'Commands'],
['/api/components', 'DOM Components'],
+ ['/api/component', ' - Component'],
['/api/panels', 'Panels'],
['/api/style_manager', 'Style Manager'],
['/api/storage_manager', 'Storage Manager'],
diff --git a/docs/README.md b/docs/README.md
index b828f099e..daef7c849 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -47,3 +47,10 @@ You can download GrapesJS from one of this sources
* `npm i grapesjs`
* git
* `git clone https://github.com/artf/grapesjs.git`
+
+
+
+
+## Changelog
+
+To track changes made in the library we rely on [Github Releases](https://github.com/artf/grapesjs/releases)
diff --git a/docs/api.js b/docs/api.js
index 33749e140..b98892483 100644
--- a/docs/api.js
+++ b/docs/api.js
@@ -10,6 +10,7 @@ const cmds = [
['block_manager/index.js', 'block_manager.md'],
['commands/index.js', 'commands.md'],
['dom_components/index.js', 'components.md'],
+ ['dom_components/model/Component.js', 'component.md'],
['panels/index.js', 'panels.md'],
['style_manager/index.js', 'style_manager.md'],
['storage_manager/index.js', 'storage_manager.md'],
diff --git a/docs/api/component.md b/docs/api/component.md
new file mode 100644
index 000000000..70ade8c7e
--- /dev/null
+++ b/docs/api/component.md
@@ -0,0 +1,413 @@
+
+
+## Component
+
+The Component object represents a single node of our template structure, so when you update its properties the changes are
+immediatly reflected on the canvas and in the code to export (indeed, when you ask to export the code we just go through all
+the tree of nodes).
+An example on how to update properties:
+
+```js
+component.set({
+ tagName: 'span',
+ attributes: { ... },
+ removable: false,
+});
+component.get('tagName');
+// -> 'span'
+```
+
+### Properties
+
+- `type` **[String][1]?** Component type, eg. `text`, `image`, `video`, etc.
+- `tagName` **[String][1]?** HTML tag of the component, eg. `span`. Default: `div`
+- `attributes` **[Object][2]?** Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}`
+- `name` **[String][1]?** Name of the component. Will be used, for example, in Layers and badges
+- `removable` **[Boolean][3]?** When `true` the component is removable from the canvas, default: `true`
+- `draggable` **([Boolean][3] \| [String][1])?** Indicates if it's possible to drag the component inside others.
+ You can also specify a query string to indentify elements,
+ eg. `'.some-class[title=Hello], [data-gjs-type=column]'` means you can drag the component only inside elements
+ containing `some-class` class and `Hello` title, and `column` components. Default: `true`
+- `droppable` **([Boolean][3] \| [String][1])?** Indicates if it's possible to drop other components inside. You can use
+ a query string as with `draggable`. Default: `true`
+- `badgable` **[Boolean][3]?** Set to false if you don't want to see the badge (with the name) over the component. Default: `true`
+- `stylable` **([Boolean][3] \| [Array][4]<[String][1]>)?** True if it's possible to style the component.
+ You can also indicate an array of CSS properties which is possible to style, eg. `['color', 'width']`, all other properties
+ will be hidden from the style manager. Default: `true`
+- `stylable-require` **[Array][4]<[String][1]>?** Indicate an array of style properties to show up which has been marked as `toRequire`. Default: `[]`
+- `unstylable` **[Array][4]<[String][1]>?** Indicate an array of style properties which should be hidden from the style manager. Default: `[]`
+- `highlightable` **[Boolean][3]?** It can be highlighted with 'dotted' borders if true. Default: `true`
+- `copyable` **[Boolean][3]?** True if it's possible to clone the component. Default: `true`
+- `resizable` **[Boolean][3]?** Indicates if it's possible to resize the component. It's also possible to pass an object as [options for the Resizer][5]. Default: `false`
+- `editable` **[Boolean][3]?** Allow to edit the content of the component (used on Text components). Default: `false`
+- `layerable` **[Boolean][3]?** Set to `false` if you need to hide the component inside Layers. Default: `true`
+- `selectable` **[Boolean][3]?** Allow component to be selected when clicked. Default: `true`
+- `hoverable` **[Boolean][3]?** Shows a highlight outline when hovering on the element if `true`. Default: `true`
+- `void` **[Boolean][3]?** This property is used by the HTML exporter as void elements don't have closing tags, eg. ` `, `
`, etc. Default: `false`
+- `content` **[String][1]?** Content of the component (not escaped) which will be appended before children rendering. Default: `''`
+- `icon` **[String][1]?** Component's icon, this string will be inserted before the name (in Layers and badge), eg. it can be an HTML string ''. Default: `''`
+- `script` **([String][1] \| [Function][6])?** Component's javascript. More about it [here][7]. Default: `''`
+- `traits` **[Array][4]<([Object][2] \| [String][1])>?** Component's traits. More about it [here][8]. Default: `['id', 'title']`
+- `propagate` **[Array][4]<[String][1]>?** Indicates an array of properties which will be inhereted by all NEW appended children.
+ For example if you create a component likes this: `{ removable: false, draggable: false, propagate: ['removable', 'draggable'] }`
+ and append some new component inside, the new added component will get the exact same properties indicated in the `propagate` array (and the `propagate` property itself). Default: `[]`
+- `toolbar` **[Array][4]<[Object][2]>?** Set an array of items to show up inside the toolbar when the component is selected (move, clone, delete).
+ Eg. `toolbar: [ { attributes: {class: 'fa fa-arrows'}, command: 'tlb-move' }, ... ]`.
+ By default, when `toolbar` property is falsy the editor will add automatically commands like `move`, `delete`, etc. based on its properties.
+- `components` **Collection<[Component][9]>?** Children components. Default: `null`
+
+## is
+
+Check component's type
+
+### Parameters
+
+- `type` **[string][1]** Component type
+
+### Examples
+
+```javascript
+component.is('image')
+// -> false
+```
+
+Returns **[Boolean][3]**
+
+## find
+
+Find inner components by query string.
+**ATTENTION**: this method works only with already rendered component
+
+### Parameters
+
+- `query` **[String][1]** Query string
+
+### Examples
+
+```javascript
+component.find('div > .class');
+// -> [Component, Component, ...]
+```
+
+Returns **[Array][4]** Array of components
+
+## closest
+
+Find the closest parent component by query string.
+**ATTENTION**: this method works only with already rendered component
+
+### Parameters
+
+- `query` **[string][1]** Query string
+
+### Examples
+
+```javascript
+component.closest('div.some-class');
+// -> Component
+```
+
+Returns **[Component][9]**
+
+## replaceWith
+
+Replace a component with another one
+
+### Parameters
+
+- `el` **([String][1] \| [Component][9])** Component or HTML string
+
+### Examples
+
+```javascript
+component.replaceWith('
Some new content
');
+// -> Component
+```
+
+Returns **([Component][9] \| [Array][4]<[Component][9]>)** New added component/s
+
+## setAttributes
+
+Update attributes of the component
+
+### Parameters
+
+- `attrs` **[Object][2]** Key value attributes
+
+### Examples
+
+```javascript
+component.setAttributes({ id: 'test', 'data-key': 'value' });
+```
+
+Returns **this**
+
+## addAttributes
+
+Add attributes to the component
+
+### Parameters
+
+- `attrs` **[Object][2]** Key value attributes
+
+### Examples
+
+```javascript
+component.addAttributes({ 'data-key': 'value' });
+```
+
+Returns **this**
+
+## getStyle
+
+Get the style of the component
+
+Returns **[Object][2]**
+
+## setStyle
+
+Set the style on the component
+
+### Parameters
+
+- `prop` **[Object][2]** Key value style object (optional, default `{}`)
+- `opts` (optional, default `{}`)
+
+### Examples
+
+```javascript
+component.setStyle({ color: 'red' });
+```
+
+Returns **[Object][2]**
+
+## getAttributes
+
+Return all component's attributes
+
+Returns **[Object][2]**
+
+## addClass
+
+Add classes
+
+### Parameters
+
+- `classes` **([Array][4]<[String][1]> | [String][1])** Array or string of classes
+
+### Examples
+
+```javascript
+model.addClass('class1');
+model.addClass('class1 class2');
+model.addClass(['class1', 'class2']);
+// -> [SelectorObject, ...]
+```
+
+Returns **[Array][4]** Array of added selectors
+
+## setClass
+
+Set classes (resets current collection)
+
+### Parameters
+
+- `classes` **([Array][4]<[String][1]> | [String][1])** Array or string of classes
+
+### Examples
+
+```javascript
+model.setClass('class1');
+model.setClass('class1 class2');
+model.setClass(['class1', 'class2']);
+// -> [SelectorObject, ...]
+```
+
+Returns **[Array][4]** Array of added selectors
+
+## removeClass
+
+Remove classes
+
+### Parameters
+
+- `classes` **([Array][4]<[String][1]> | [String][1])** Array or string of classes
+
+### Examples
+
+```javascript
+model.removeClass('class1');
+model.removeClass('class1 class2');
+model.removeClass(['class1', 'class2']);
+// -> [SelectorObject, ...]
+```
+
+Returns **[Array][4]** Array of removed selectors
+
+## append
+
+Add new component children
+
+### Parameters
+
+- `components` **([Component][9] \| [String][1])** Component to add
+- `opts` **[Object][2]** Options, same as in `model.add()`(from backbone) (optional, default `{}`)
+
+### Examples
+
+```javascript
+someComponent.get('components').length // -> 0
+const videoComponent = someComponent.append('')[0];
+// This will add 2 components (`video` and `div`) to your `someComponent`
+someComponent.get('components').length // -> 2
+// You can pass components directly
+otherComponent.append(otherComponent2);
+otherComponent.append([otherComponent3, otherComponent4]);
+```
+
+Returns **[Array][4]** Array of appended components
+
+## components
+
+Set new collection if `components` are provided, otherwise the
+current collection is returned
+
+### Parameters
+
+- `components` **([Component][9] \| [String][1])?** Components to set
+
+### Examples
+
+```javascript
+// Set new collection
+component.components('');
+// Get current collection
+const collection = component.components();
+console.log(collection.length);
+// -> 2
+```
+
+Returns **(Collection | [Array][4]<[Component][9]>)**
+
+## parent
+
+Get the parent component, if exists
+
+### Examples
+
+```javascript
+component.parent();
+// -> Component
+```
+
+Returns **[Component][9]**
+
+## getName
+
+Get the name of the component
+
+Returns **[String][1]**
+
+## getIcon
+
+Get the icon string
+
+Returns **[String][1]**
+
+## toHTML
+
+Return HTML string of the component
+
+### Parameters
+
+- `opts` **[Object][2]** Options (optional, default `{}`)
+ - `opts.attributes` **([Object][2] \| [Function][6])** You can pass an object of custom attributes to replace
+ with the current one or you can even pass a function to generate attributes dynamically (optional, default `null`)
+
+### Examples
+
+```javascript
+// Simple HTML return
+component.set({ tagName: 'span' });
+component.setAttributes({ title: 'Hello' });
+component.toHTML();
+// ->
+
+// Custom attributes
+component.toHTML({ attributes: { 'data-test': 'Hello' } });
+// ->
+
+// Custom dynamic attributes
+component.toHTML({
+ attributes(component, attributes) {
+ if (component.get('tagName') == 'span') {
+ attributes.title = 'Custom attribute';
+ }
+ return attributes;
+ },
+});
+// ->
+```
+
+Returns **[String][1]** HTML string
+
+## getId
+
+Return the component id
+
+Returns **[String][1]**
+
+## setId
+
+Set new id on the component
+
+### Parameters
+
+- `id` **[String][1]**
+
+Returns **this**
+
+## getEl
+
+Get the DOM element of the component. This works only of the
+component is already rendered
+
+Returns **[HTMLElement][10]**
+
+## onAll
+
+Execute callback function on itself and all inner components
+
+### Parameters
+
+- `clb` **[Function][6]** Callback function, the model is passed as an argument
+
+### Examples
+
+```javascript
+component.onAll(component => {
+ // do something with component
+})
+```
+
+Returns **this**
+
+[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
+
+[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
+
+[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
+
+[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
+
+[5]: https://github.com/artf/grapesjs/blob/master/src/utils/Resizer.js
+
+[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
+
+[7]: /modules/Components-js.html
+
+[8]: /modules/Traits.html
+
+[9]: #component
+
+[10]: https://developer.mozilla.org/docs/Web/HTML/Element
diff --git a/src/dom_components/model/Component.js b/src/dom_components/model/Component.js
index bcaef6964..6ea8677cd 100644
--- a/src/dom_components/model/Component.js
+++ b/src/dom_components/model/Component.js
@@ -29,121 +29,90 @@ const escapeRegExp = str => {
const avoidInline = em => em && em.getConfig('avoidInlineStyle');
+/**
+ * The Component object represents a single node of our template structure, so when you update its properties the changes are
+ * immediatly reflected on the canvas and in the code to export (indeed, when you ask to export the code we just go through all
+ * the tree of nodes).
+ * An example on how to update properties:
+ * ```js
+ * component.set({
+ * tagName: 'span',
+ * attributes: { ... },
+ * removable: false,
+ * });
+ * component.get('tagName');
+ * // -> 'span'
+ * ```
+ *
+ * @typedef Component
+ * @property {String} [type=''] Component type, eg. `text`, `image`, `video`, etc.
+ * @property {String} [tagName='div'] HTML tag of the component, eg. `span`. Default: `div`
+ * @property {Object} [attributes={}] Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}`
+ * @property {String} [name=''] Name of the component. Will be used, for example, in Layers and badges
+ * @property {Boolean} [removable=true] When `true` the component is removable from the canvas, default: `true`
+ * @property {Boolean|String} [draggable=true] Indicates if it's possible to drag the component inside others.
+ * You can also specify a query string to indentify elements,
+ * eg. `'.some-class[title=Hello], [data-gjs-type=column]'` means you can drag the component only inside elements
+ * containing `some-class` class and `Hello` title, and `column` components. Default: `true`
+ * @property {Boolean|String} [droppable=true] Indicates if it's possible to drop other components inside. You can use
+ * a query string as with `draggable`. Default: `true`
+ * @property {Boolean} [badgable=true] Set to false if you don't want to see the badge (with the name) over the component. Default: `true`
+ * @property {Boolean|Array} [stylable=true] True if it's possible to style the component.
+ * You can also indicate an array of CSS properties which is possible to style, eg. `['color', 'width']`, all other properties
+ * will be hidden from the style manager. Default: `true`
+ * @property {Array} [stylable-require=[]] Indicate an array of style properties to show up which has been marked as `toRequire`. Default: `[]`
+ * @property {Array} [unstylable=[]] Indicate an array of style properties which should be hidden from the style manager. Default: `[]`
+ * @property {Boolean} [highlightable=true] It can be highlighted with 'dotted' borders if true. Default: `true`
+ * @property {Boolean} [copyable=true] True if it's possible to clone the component. Default: `true`
+ * @property {Boolean} [resizable=false] Indicates if it's possible to resize the component. It's also possible to pass an object as [options for the Resizer](https://github.com/artf/grapesjs/blob/master/src/utils/Resizer.js). Default: `false`
+ * @property {Boolean} [editable=false] Allow to edit the content of the component (used on Text components). Default: `false`
+ * @property {Boolean} [layerable=true] Set to `false` if you need to hide the component inside Layers. Default: `true`
+ * @property {Boolean} [selectable=true] Allow component to be selected when clicked. Default: `true`
+ * @property {Boolean} [hoverable=true] Shows a highlight outline when hovering on the element if `true`. Default: `true`
+ * @property {Boolean} [void=false] This property is used by the HTML exporter as void elements don't have closing tags, eg. ` `, ``, etc. Default: `false`
+ * @property {String} [content=''] Content of the component (not escaped) which will be appended before children rendering. Default: `''`
+ * @property {String} [icon=''] Component's icon, this string will be inserted before the name (in Layers and badge), eg. it can be an HTML string ''. Default: `''`
+ * @property {String|Function} [script=''] Component's javascript. More about it [here](/modules/Components-js.html). Default: `''`
+ * @property {Array