Skip to content

Instantly share code, notes, and snippets.

@erdomke
Last active February 15, 2023 01:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erdomke/12d85175636df8589888dbcfedfb6961 to your computer and use it in GitHub Desktop.
Save erdomke/12d85175636df8589888dbcfedfb6961 to your computer and use it in GitHub Desktop.
Grapes.js TypeScript Definitions
declare namespace Backbone {
class Model<T> {
constructor(attr?:T, opt?:any)
attributes : T
collection: Collection<this>
cid: string
get<K extends keyof T>(prop:K) : T[K]
set<K extends keyof T>(prop:K , val:T[K]) : void
defaults() : T
on(eventName: string, callback: (...args: any[]) => void)
toJSON(options?: any): any
}
class Collection<TModel extends Model> {
models: TModel[];
length: number;
add(model: {} | TModel): TModel;
add(models: Array<{} | TModel>): TModel[];
find(iterator: (item : TModel) => boolean, context?: any): TModel;
remove(model: {} | TModel): TModel;
remove(models: Array<{} | TModel>): TModel[];
reset(models?: Array<{} | TModel>): TModel[];
}
}
declare module grapesjs {
interface EditorConfig {
/** Selector which indicates where render the editor */
container?: string | HTMLElement
/** If true, auto-render the content */
autorender? : boolean = true
/** Array of plugins to execute on start */
plugins? : []
/** Custom options for plugins */
pluginsOpts?: Record<string, any>
/** Init headless editor */
headless?: boolean = false
/** Style prefix */
stylePrefix?: string
/** HTML string or object of components */
components?: string,
/** CSS string or object of rules */
style?: string,
/** If true, will fetch HTML and CSS from selected container */
fromElement?: boolean,
/** Show an alert before unload the page with unsaved changes */
noticeOnUnload?: number,
/** Show paddings and margins */
showOffsets?: boolean,
/** Show paddings and margins on selected component */
showOffsetsSelected?: boolean,
/** On creation of a new Component (via object), if the 'style' attribute is not
* empty, all those roles will be moved in its new class */
forceClass?: boolean,
/** Height for the editor container */
height?: string,
/** Width for the editor container */
width?: string,
/** Type of logs to print with the logger (by default is used the devtool console).
* Available by default: debug, info, warning, error
* You can use `false` to disable all of them or `true` to print all of them */
log?: ('debug'|'info'|'warning'|'error')[]
/** By default Grapes injects base CSS into the canvas. For example, it sets body margin to 0
* and sets a default background color of white. This CSS is desired in most cases.
* use this property if you wish to overwrite the base CSS to your own CSS. This is most
* useful if for example your template is not based off a document with 0 as body margin. */
baseCss?: string,
/** CSS that could only be seen (for instance, inside the code viewer) */
protectedCss?: string,
/** CSS for the iframe which containing the canvas, useful if you need to custom something inside
* (eg. the style of the selected component) */
canvasCss?: string,
/** Default command */
defaultCommand?: string,
/** Show a toolbar when the component is selected */
showToolbar?: boolean,
// Allow script tag importing
// @deprecated in favor of `config.parser.optionsHtml.allowScripts`
// allowScripts: 0,
/** If true render a select of available devices */
showDevices?: boolean,
/** When enabled, on device change media rules won't be created */
devicePreviewMode?: boolean,
/** The condition to use for media queries, eg. 'max-width'
* Comes handy for mobile-first cases */
mediaCondition?: string,
/** Starting tag for variable inside scripts in Components */
tagVarStart?: string,
/** Ending tag for variable inside scripts in Components */
tagVarEnd?: string,
/** When false, removes empty text nodes when parsed, unless they contain a space */
keepEmptyTextNodes?: boolean,
/** Return JS of components inside HTML from 'editor.getHtml()' */
jsInHtml?: boolean,
/** Enable native HTML5 drag and drop */
nativeDnD?: boolean,
/** Enable multiple selection */
multipleSelection?: boolean,
/** Show the wrapper component in the final code, eg. in editor.getHtml() */
exportWrapper?: boolean,
/** The wrapper, if visible, will be shown as a `<body>` */
wrapperIsBody?: boolean,
/** Pass default available options wherever `editor.getHtml()` is called */
optsHtml?: Record<string, any>,
/** Pass default available options wherever `editor.getCss()` is called */
optsCss?: Record<string, any>,
/** Usually when you update the `style` of the component this changes the
* element's `style` attribute. Unfortunately, inline styling doesn't allow
* use of media queries (@media) or even pseudo selectors (eg. :hover).
* When `avoidInlineStyle` is true all styles are inserted inside the css rule
* @deprecated Don't use this option, we don't support inline styling anymore */
avoidInlineStyle?: boolean,
/** Avoid default properties from storable JSON data, like `components` and `styles`.
* With this option enabled your data will be smaller (usefull if need to
* save some storage space) */
avoidDefaults?: boolean,
/** (experimental)
* The structure of components is always on the screen but it's not the same
* for style rules. When you delete a component you might leave a lot of styles
* which will never be used again, therefore they might be removed.
* With this option set to true, styles not used from the CSS generator (so in
* any case where `CssGenerator.build` is used) will be removed automatically.
* But be careful, not always leaving the style not used mean you wouldn't
* use it later, but this option comes really handy when deal with big templates. */
clearStyles?: boolean,
/** Specify the global drag mode of components. By default, components are moved
* following the HTML flow. Two other options are available:
* 'absolute' - Move components absolutely (design tools way)
* 'translate' - Use translate CSS from transform property
* To get more about this feature read: https://github.com/artf/grapesjs/issues/1936 */
dragMode?: boolean,
/** When the editor is placed in a scrollable container (eg. modals) this might
* cause elements inside the canvas (eg. floating toolbars) to be misaligned.
* To avoid that, you can specify an array of DOM elements on which their scroll will
* trigger the canvas update.
* Be default, if the array is empty, the first parent element will be appended.
* listenToEl: [document.querySelector('#scrollable-el')], */
listenToEl?: HTMLElement[],
/** Import asynchronously CSS to use as icons */
cssIcons?: string,
/** Dom element */
el?: string,
/** Configurations for I18n */
i18n?: Record<string, any>,
/** Configurations for Undo Manager */
undoManager?: Record<string, any> | boolean,
/** Configurations for Asset Manager */
assetManager?: AssetManagerConfig | boolean,
/** Configurations for Canvas */
canvas?: CanvasConfig | boolean,
/** Configurations for Layers */
layers?: Record<string, any> | boolean,
/** Configurations for Storage Manager */
storageManager?: StorageManagerConfig | boolean,
/** Configurations for Rich Text Editor */
richTextEditor?: RichTextEditorConfig | boolean,
/** Configurations for DomComponents */
domComponents?: DomComponentsConfig | boolean,
/** Configurations for Modal Dialog */
modal?: ModalConfig | boolean,
/** Configurations for Code Manager */
codeManager?: CodeManagerConfig | boolean,
/** Configurations for Panels */
panels?: PanelsConfig | boolean,
/** Configurations for Commands */
commands?: CommandsConfig | boolean,
/** Configurations for Css Composer */
cssComposer?: CssComposerConfig | boolean,
/** Configurations for Selector Manager */
selectorManager?: SelectorManagerConfig | boolean,
/** Configurations for Device Manager */
deviceManager?: DeviceManagerConfig | boolean,
/** Configurations for Style Manager */
styleManager?: StyleManagerConfig | boolean,
/** Configurations for Block Manager */
blockManager?: BlockManagerConfig | boolean,
/** Configurations for Trait Manager */
traitManager?: TraitManagerConfig | boolean,
/** Texts **/
textViewCode?: string,
/** Keep unused styles within the editor **/
keepUnusedStyles?: 0,
}
interface AssetManagerConfig {
assets?: Array<object>;
noAssets?: string;
stylePrefix?: string;
upload?: boolean;
uploadName?: string;
headers?: object;
params?: object;
credentials?: RequestCredentials;
multiUpload?: boolean;
autoAdd?: boolean;
uploadText?: string;
addBtnText?: string;
customFetch?: Function;
uploadFile?: Function;
embedAsBase64?: boolean;
handleAdd?: Function;
dropzone?: boolean;
openAssetsOnDrop?: number;
dropzoneContent?: string;
modalTitle?: string;
inputPlaceholder?: string;
}
interface CanvasConfig {
stylePrefix?: string;
scripts?: Array<string>;
styles?: Array<string>;
customBadgeLabel?: Function;
autoscrollLimit?: number;
notTextable?: Array<string>;
}
interface StyleManagerConfig {
stylePrefix?: string;
sectors?: Array<object>;
appendTo?: HTMLElement | string;
textNoElement?: string;
hideNotStylable?: boolean;
highlightChanged?: boolean;
highlightComputed?: boolean;
showComputed?: boolean;
clearProperties?: boolean;
avoidComputed?: Array<string>;
}
interface BlockManagerConfig {
appendTo?: HTMLElement | string;
blocks: Array<object>;
}
interface RichTextEditorConfig {
stylePrefix?: string;
adjustToolbar?: boolean;
actions?: Array<string>;
}
interface TraitManagerConfig {
stylePrefix?: string;
appendTo?: HTMLElement | string;
labelContainer?: string;
labelPlhText?: string;
labelPlhRef?: string;
optionsTarget?: Array<object>;
textNoElement?: string;
}
interface StorageManagerConfig {
id?: string;
autosave?: boolean;
autoload?: boolean;
type?: "local" | "remote";
stepsBeforeSave?: number;
storeComponents?: boolean;
storeStyles?: boolean;
storeHtml?: boolean;
storeCss?: boolean;
checkLocal?: boolean;
params?: object;
headers?: object;
urlStore?: string;
urlLoad?: string;
contentTypeJson?: boolean;
credentials?: RequestCredentials;
beforeSend(jqXHR: any, settings: object): void;
onComplete(jqXHR: any, status: any): void;
}
interface DomComponentsConfig {
stylePrefix?: string;
wrapperId?: string;
wrapperName?: string;
wrapper?: DomComponentsWrapperConfig;
components?: Array<object>;
imageCompClass?: string;
oAssetsOnCreate?: boolean;
storeWrapper?: boolean;
voidElements?: Array<string>;
}
interface DomComponentsWrapperConfig {
removable?: boolean,
copyable?: boolean,
draggable?: boolean,
// TODO: Type custom blocks and components
components?: Array<object>,
traits?: Array<object>,
stylable?: Array<string>
}
interface ModalConfig {
stylePrefix?: string;
title?: string;
content?: string;
backdrop?: boolean;
}
interface CodeManagerConfig {
stylePrefix?: string;
inlineCss?: boolean;
}
interface PanelsConfig {
stylePrefix?: string;
defaults?: Array<object>;
em?: object;
delayBtnsShow?: number;
}
interface CommandsConfig {
ESCAPE_KEY?: number;
stylePrefix?: string;
defaults?: Array<object>;
em?: object;
firstCentered?: boolean;
newFixedH?: boolean;
minComponentH?: number;
minComponentW?: number;
}
interface CssComposerConfig {
stylePrefix?: string;
staticRules?: string;
rules?: Array<string>;
}
interface SelectorManagerConfig {
stylePrefix?: string;
appendTo?: HTMLElement | string;
selectors?: Array<string>;
label?: string;
statesLabel?: string;
selectedLabel?: string;
states?: Array<object>;
}
interface DeviceManagerConfig {
devices?: Array<object>;
deviceLabel?: string;
}
function init(config : EditorConfig) : Editor;
interface Trait extends Backbone.Model<TraitOptions> {
target : Component
/** Return all the properties */
props() : TraitOptions;
targetUpdated() : void;
getValue(): string;
getTargetValue(): string;
setTargetValue(value: any, opts = {}) : void
setValueFromInput(value : any, final = 1, opts = {}) : void
/**
* Get the initial value of the trait
*/
getInitValue() : string
}
type TraitType = 'text'
| 'number'
| 'checkbox'
| 'select'
| string
interface TraitOptions {
type: TraitType;
label: string,
name: string,
min?: string,
max?: string,
unit?: string,
step?: number,
value?: string,
target?: Component,
default?: string,
placeholder?: string,
changeProp?: number,
options?: SelectOption[]
[key: string]: any
}
interface PanelOptions {
id: string,
content: string,
visible: boolean,
buttons: Button[],
}
interface Panel extends Backbone.Model<PanelOptions> {
}
interface Button extends Backbone.Model<ButtonOptions> {
}
interface ButtonOptions {
id: string,
label: string,
tagName: 'span',
className: string,
command: string | ((editor : Editor, opts? : any) => void),
context: string,
buttons: any[],
attributes: object,
options: object,
active: boolean,
dragDrop: boolean,
togglable: boolean,
runDefaultCommand: boolean,
stopDefaultCommand: boolean,
disable: boolean
}
interface ComponentView {
model : Component
onRender(opts: {
editor?: Editor,
model? : Component,
el? : HTMLElement
}) : void;
}
interface View {}
interface LayerManager {
/**
* Set new root for layers
* @param el Component to be set as the root
*/
setRoot(el : HTMLElement|Component|String) : this
/** Get the root of layers */
getRoot() : Component
/** Return the view of layers */
getAll() : View
}
interface TraitView {
noLabel?: boolean
templateInput?: string | ((options: {
trait : Trait
}) => string)
eventCapture? : string[]
onEvent? : (options: {
elInput : HTMLElement,
component : Component,
event : any
}) => void
onUpdate? : (options: {
elInput : HTMLElement,
component : Component
}) => void
createInput? : (options: {
trait : Trait
}) => HTMLElement
createLabel?: (options: {
label : string
}) => string
}
interface TraitManager {
/**
* Add new trait type
* @param name Type name
* @param methods Object representing the trait
*/
addType(name : string, trait : TraitView) : void
/**
* Get trait type
* @param name Type name
*/
getType(name : string) : Object
/**
* Get all trait types
*/
getTypes() : Object
}
/**
* Editor contains the top level API which you'll probably use to customize the editor or extend it with plugins.
* You get the Editor instance on init method and you can pass options via its [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/editor/config/config.js)
*
* ```js
* const editor = grapesjs.init({
* // options
* });
* ```
*
* ## Available Events
*
* You can make use of available events in this way
* ```js
* editor.on('EVENT-NAME', (some, argument) => {
* // do something
* })
* ```
*
* * `update` - The structure of the template is updated (its HTML/CSS)
* * `undo` - Undo executed
* * `redo` - Redo executed
* * `load` - Editor is loaded
*
* ### Components
* Check the [Components](/api/components.html) module.
* ### Keymaps
* Check the [Keymaps](/api/keymaps.html) module.
* ### Style Manager
* Check the [Style Manager](/api/style_manager.html) module.
* ### Storage
* Check the [Storage](/api/storage_manager.html) module.
* ### Canvas
* Check the [Canvas](/api/canvas.html) module.
* ### RTE
* Check the [Rich Text Editor](/api/rich_text_editor.html) module.
* ### Commands
* Check the [Commands](/api/commands.html) module.
* ### Selectors
* Check the [Selectors](/api/selector_manager.html) module.
* ### Blocks
* Check the [Blocks](/api/block_manager.html) module.
* ### Assets
* Check the [Assets](/api/assets.html) module.
* ### Modal
* Check the [Modal](/api/modal_dialog.html) module.
* ### Devices
* Check the [Devices](/api/device_manager.html) module.
* ### Parser
* Check the [Parser](/api/parser.html) module.
* ### Pages
* Check the [Pages](/api/pages.html) module.
*
* ## Methods
*/
interface Editor {
DomComponents: Components;
LayerManager: LayerManager;
CssComposer: CssComposer;
StorageManager: StorageManager;
AssetManager: AssetManager;
BlockManager: BlockManager;
TraitManager: TraitManager;
SelectorManager: SelectorManager;
CodeManager: object;
Commands: Commands;
Keymaps: Keymaps;
Modal: Modal;
Panels: Panels;
StyleManager: StyleManager;
Canvas: Canvas;
UndoManager: UndoManager;
DeviceManager: object;
RichTextEditor: RichTextEditor;
Parser: Parser;
Utils: object;
Config: EditorConfig | object;
/**
* Returns configuration object
* @param [prop] - Property name
* @returns Returns the configuration object or
* the value of the specified property
*/
getConfig(prop?: string): EditorConfig | object;
/**
* Returns HTML built inside canvas
* @param [opts = {}] - Options
* @param [opts.component] - Return the HTML of a specific Component
* @param [opts.cleanId = false] - Remove unnecessary IDs (eg. those created automatically)
* @returns HTML string
*/
getHtml(opts?: {
component?: Component;
cleanId?: boolean;
}): string;
/**
* Returns CSS built inside canvas
* @param [opts = {}] - Options
* @param [opts.component] - Return the CSS of a specific Component
* @param [opts.json = false] - Return an array of CssRules instead of the CSS string
* @param [opts.avoidProtected = false] - Don't include protected CSS
* @param [opts.onlyMatched = false] - Return only rules matched by the passed component.
* @returns CSS string or array of CssRules
*/
getCss(opts?: {
component?: Component;
json?: boolean;
avoidProtected?: boolean;
onlyMatched?: boolean;
}): string | CssRule[];
/**
* Returns JS of all components
* @param [opts = {}] - Options
* @param [opts.component] - Get the JS of a specific component
* @returns JS string
*/
getJs(opts?: {
component?: Component;
}): string;
/**
* Return the complete tree of components. Use `getWrapper` to include also the wrapper
*/
getComponents(): Components;
/**
* Return the wrapper and its all components
*/
getWrapper(): Component;
/**
* Set components inside editor's canvas. This method overrides actual components
* @example
* editor.setComponents('<div class="cls">New component</div>');
* // or
* editor.setComponents({
* type: 'text',
* classes:['cls'],
* content: 'New component'
* });
* @param components - HTML string or components model
* @param opt - the options object to be used by the [setComponents]{@link em#setComponents} method
*/
setComponents(components: object[] | any | string, opt: any): any;
/**
* Add components
* @example
* editor.addComponents('<div class="cls">New component</div>');
* // or
* editor.addComponents({
* type: 'text',
* classes:['cls'],
* content: 'New component'
* });
* @param components - HTML string or components model
* @param opts - Options
* @param [opts.avoidUpdateStyle = false] - If the HTML string contains styles,
* by default, they will be created and, if already exist, updated. When this option
* is true, styles already created will not be updated.
*/
addComponents(components: object[] | any | string, opts: {
avoidUpdateStyle?: boolean;
}): Component[];
/**
* Returns style in JSON format object
*/
getStyle(): any;
/**
* Set style inside editor's canvas. This method overrides actual style
* @example
* editor.setStyle('.cls{color: red}');
* //or
* editor.setStyle({
* selectors: ['cls'],
* style: { color: 'red' }
* });
* @param style - CSS string or style model
*/
setStyle(style: object[] | any | string): Editor;
/**
* Add styles to the editor
* @example
* editor.addStyle('.cls{color: red}');
* @param style - CSS string or style model
* @returns Array of created CssRule instances
*/
addStyle(style: object[] | any | string): CssRule[];
/**
* Returns the last selected component, if there is one
*/
getSelected(): Backbone.Model;
/**
* Returns an array of all selected components
*/
getSelectedAll(): Backbone.Model[];
/**
* Get a stylable entity from the selected component.
* If you select a component without classes the entity is the Component
* itself and all changes will go inside its 'style' attribute. Otherwise,
* if the selected component has one or more classes, the function will
* return the corresponding CSS Rule
*/
getSelectedToStyle(): Backbone.Model;
/**
* Select a component
* @example
* // Select dropped block
* editor.on('block:drag:stop', function(model) {
* editor.select(model);
* });
* @param el - Component to select
* @param [opts] - Options
* @param [opts.scroll] - Scroll canvas to the selected element
*/
select(el: Component | HTMLElement, opts?: {
scroll?: boolean;
}): Editor;
/**
* Add component to selection
* @example
* editor.selectAdd(model);
* @param el - Component to select
*/
selectAdd(el: Component | HTMLElement | any[]): Editor;
/**
* Remove component from selection
* @example
* editor.selectRemove(model);
* @param el - Component to select
*/
selectRemove(el: Component | HTMLElement | any[]): Editor;
/**
* Toggle component selection
* @example
* editor.selectToggle(model);
* @param el - Component to select
*/
selectToggle(el: Component | HTMLElement | any[]): Editor;
/**
* Returns, if active, the Component enabled in rich text editing mode.
* @example
* const textComp = editor.getEditing();
* if (textComp) {
* console.log('HTML: ', textComp.toHTML());
* }
*/
getEditing(): Component | null;
/**
* Set device to the editor. If the device exists it will
* change the canvas to the proper width
* @example
* editor.setDevice('Tablet');
* @param name - Name of the device
*/
setDevice(name: string): Editor;
/**
* Return the actual active device
* @example
* var device = editor.getDevice();
* console.log(device);
* // 'Tablet'
* @returns Device name
*/
getDevice(): string;
/**
* Execute command
* @example
* editor.runCommand('myCommand', {someValue: 1});
* @param id - Command ID
* @param options - Custom options
* @returns The return is defined by the command
*/
runCommand(id: string, options: any): any;
/**
* Stop the command if stop method was provided
* @example
* editor.stopCommand('myCommand', {someValue: 1});
* @param id - Command ID
* @param options - Custom options
* @returns The return is defined by the command
*/
stopCommand(id: string, options: any): any;
/**
* Store data to the current storage
* @param clb - Callback function
* @returns Stored data
*/
store(clb: (...params: any[]) => any): any;
/**
* Get the JSON data object, which could be stored and loaded back with `editor.loadData(json)`
* @example
* console.log(editor.storeData());
* // { pages: [...], styles: [...], ... }
*/
storeData(): any;
/**
* Load data from the current storage
* @param clb - Callback function
* @returns Stored data
*/
load(clb: (...params: any[]) => any): any;
/**
* Load data from the JSON data object
* @example
* editor.loadData({ pages: [...], styles: [...], ... })
* @param data - Data to load
* @returns Loaded object
*/
loadData(data: any): any;
/**
* Returns container element. The one which was indicated as 'container'
* on init method
*/
getContainer(): HTMLElement;
/**
* Return the count of changes made to the content and not yet stored.
* This count resets at any `store()`
*/
getDirtyCount(): number;
/**
* Update editor dimension offsets
*
* This method could be useful when you update, for example, some position
* of the editor element (eg. canvas, panels, etc.) with CSS, where without
* refresh you'll get misleading position of tools
* @param [options] - Options
* @param [options.tools = false] - Update the position of tools (eg. rich text editor, component highlighter, etc.)
*/
refresh(options?: {
tools?: boolean;
}): void;
/**
* Replace the built-in Rich Text Editor with a custom one.
* @example
* editor.setCustomRte({
* // Function for enabling custom RTE
* // el is the HTMLElement of the double clicked Text Component
* // rte is the same instance you have returned the first time you call
* // enable(). This is useful if need to check if the RTE is already enabled so
* // ion this case you'll need to return the RTE and the end of the function
* enable: function(el, rte) {
* rte = new MyCustomRte(el, {}); // this depends on the Custom RTE API
* ...
* return rte; // return the RTE instance
* },
*
* // Disable the editor, called for example when you unfocus the Text Component
* disable: function(el, rte) {
* rte.blur(); // this depends on the Custom RTE API
* }
*
* // Called when the Text Component is focused again. If you returned the RTE instance
* // from the enable function, the enable won't be called again instead will call focus,
* // in this case to avoid double binding of the editor
* focus: function (el, rte) {
* rte.focus(); // this depends on the Custom RTE API
* }
* });
* @param obj - Custom RTE Interface
*/
setCustomRte(obj: any): void;
/**
* Replace the default CSS parser with a custom one.
* The parser function receives a CSS string as a parameter and expects
* an array of CSSRule objects as a result. If you need to remove the
* custom parser, pass `null` as the argument
* @example
* editor.setCustomParserCss(css => {
* const result = [];
* // ... parse the CSS string
* result.push({
* selectors: '.someclass, div .otherclass',
* style: { color: 'red' }
* })
* // ...
* return result;
* });
* @param parser - Parser function
*/
setCustomParserCss(parser: ((...params: any[]) => any) | null): Editor;
/**
* Change the global drag mode of components.
* To get more about this feature read: https://github.com/artf/grapesjs/issues/1936
* @param value - Drag mode, options: 'absolute' | 'translate'
*/
setDragMode(value: string): Editor;
/**
* Trigger event log message
* @example
* editor.log('Something done!', { ns: 'from-plugin-x', level: 'info' });
* // This will trigger following events
* // `log`, `log:info`, `log-from-plugin-x`, `log-from-plugin-x:info`
* // Callbacks of those events will always receive the message and
* // options, as arguments, eg:
* // editor.on('log:info', (msg, opts) => console.info(msg, opts))
* @param msg - Message to log
* @param [opts = {}] - Custom options
* @param [opts.ns = ''] - Namespace of the log (eg. to use in plugins)
* @param [opts.level = 'debug'] - Level of the log, `debug`, `info`, `warning`, `error`
*/
log(msg: any, opts?: {
ns?: string;
level?: string;
}): Editor;
/**
* Translate label
* @example
* editor.t('msg');
* // use params
* editor.t('msg2', { params: { test: 'hello' } });
* // custom local
* editor.t('msg2', { params: { test: 'hello' }, l: 'it' });
* @param key - Label to translate
* @param [opts] - Options for the translation
* @param [opts.params] - Params for the translation
* @param [opts.noWarn] - Avoid warnings in case of missing resources
*/
t(key: string, opts?: {
params?: any;
noWarn?: boolean;
}): string;
/**
* Attach event
* @param event - Event name
* @param callback - Callback function
*/
on(event: GrapesEvent, callback: (...params: any[]) => any): Editor;
/**
* Attach event and detach it after the first run
* @param event - Event name
* @param callback - Callback function
*/
once(event: GrapesEvent, callback: (...params: any[]) => any): Editor;
/**
* Detach event
* @param event - Event name
* @param callback - Callback function
*/
off(event: GrapesEvent, callback: (...params: any[]) => any): Editor;
/**
* Trigger event
* @param event - Event to trigger
*/
trigger(event: GrapesEvent): Editor;
/**
* Destroy the editor
*/
destroy(): void;
/**
* Render editor
*/
render(): HTMLElement;
/**
* Trigger a callback once the editor is loaded and rendered.
* The callback will be executed immediately if the method is called on the already rendered editor.
* @example
* editor.onReady(() => {
* // perform actions
* });
* @param clb - Callback to trigger
*/
onReady(clb: (...params: any[]) => any): void;
/**
* Print safe HTML by using ES6 tagged template strings.
* @example
* const unsafeStr = '<script>....</script>';
* const safeStr = '<b>Hello</b>';
* // Use `$${var}` to avoid escaping
* const strHtml = editor.html`Escaped ${unsafeStr}, unescaped $${safeStr}`;
*/
html(literals: string[], substs: string[]): string;
}
type GrapesEvent = ComponentEvent
| BlockEvent
| AssetEvent
| KeymapEvent
| StyleManagerEvent
| StorageEvent
| CanvasEvent
| SelectorEvent
| RichTextEditorEvent
| ModalEvent
| CommandEvent
| GeneralEvent;
type ComponentEvent =
'component:create'
| 'component:mount'
| 'component:add'
| 'component:remove'
| 'component:remove:before'
| 'component:clone'
| 'component:update'
| 'component:styleUpdate'
| 'component:selected'
| 'component:deselected'
| 'component:toggled'
| 'component:type:add'
| 'component:type:update'
| 'component:drag:start'
| 'component:drag'
| 'component:drag:end';
type BlockEvent =
"block:add"
| "block:remove"
| "block:drag:start"
| "block:drag"
| "block:drag:stop";
type AssetEvent =
"asset:add"
| "asset:remove"
| "asset:upload:start"
| "asset:upload:end"
| "asset:upload:error"
| "asset:upload:response";
type KeymapEvent =
"keymap:add"
| "keymap:remove"
| "keymap:emit"
| "keymap:emit:{keymapId}";
type StyleManagerEvent =
"styleManager:update:target"
| "styleManager:change"
| "styleManager:change:{propertyName}";
type StorageEvent =
"storage:start"
| "storage:start:store"
| "storage:start:load"
| "storage:load"
| "storage:store"
| "storage:end"
| "storage:end:store"
| "storage:end:load"
| "storage:error"
| "storage:error:store"
| "storage:error:load";
type CanvasEvent =
"canvas:dragenter"
| "canvas:dragover"
| "canvas:drop"
| "canvas:dragend"
| "canvas:dragdata";
type SelectorEvent = "selector:add";
type RichTextEditorEvent = "rte:enable" | "rte:disable";
type ModalEvent = "modal:open" | "modal:close";
type CommandEvent =
"run:{commandName}"
| "stop:{commandName}"
| "run:{commandName}:before"
| "stop:{commandName}:before"
| "abort:{commandName}";
type GeneralEvent =
"canvasScroll"
| "undo"
| "redo"
| "load";
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/asset_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* assetManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const assetManager = editor.AssetManager;
* ```
*
* ## Available Events
* * `asset:open` - Asset Manager opened.
* * `asset:close` - Asset Manager closed.
* * `asset:add` - Asset added. The [Asset] is passed as an argument to the callback.
* * `asset:remove` - Asset removed. The [Asset] is passed as an argument to the callback.
* * `asset:update` - Asset updated. The updated [Asset] and the object containing changes are passed as arguments to the callback.
* * `asset:upload:start` - Before the upload is started.
* * `asset:upload:end` - After the upload is ended.
* * `asset:upload:error` - On any error in upload, passes the error as an argument.
* * `asset:upload:response` - On upload response, passes the result as an argument.
* * `asset` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.
* * `asset:custom` - Event for handling custom Asset Manager UI.
*
* ## Methods
* * [open](#open)
* * [close](#close)
* * [isOpen](#isopen)
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [getAllVisible](#getallvisible)
* * [remove](#remove)
* * [store](#store)
* * [load](#load)
* * [getContainer](#getcontainer)
*
* [Asset]: asset.html
*/
interface AssetManager {
/**
* Open the asset manager.
* @example
* assetManager.open({
* select(asset, complete) {
* const selected = editor.getSelected();
* if (selected && selected.is('image')) {
* selected.addAttributes({ src: asset.getSrc() });
* // The default AssetManager UI will trigger `select(asset, false)` on asset click
* // and `select(asset, true)` on double-click
* complete && assetManager.close();
* }
* }
* });
* // with your custom types (you should have assets with those types declared)
* assetManager.open({ types: ['doc'], ... });
* @param [options] - Options for the asset manager.
* @param [options.types = ['image']] - Types of assets to show.
* @param [options.select] - Type of operation to perform on asset selection. If not specified, nothing will happen.
*/
open(options?: {
types?: String[];
select?: (...params: any[]) => any;
}): void;
/**
* Close the asset manager.
* @example
* assetManager.close();
*/
close(): void;
/**
* Checks if the asset manager is open
* @example
* assetManager.isOpen(); // true | false
*/
isOpen(): boolean;
/**
* Add new asset/s to the collection. URLs are supposed to be unique
* @example
* // As strings
* assetManager.add('http://img.jpg');
* assetManager.add(['http://img.jpg', './path/to/img.png']);
*
* // Using objects you can indicate the type and other meta informations
* assetManager.add({
* // type: 'image', // image is default
* src: 'http://img.jpg',
* height: 300,
* width: 200,
* });
* assetManager.add([{ src: 'img2.jpg' }, { src: 'img2.png' }]);
* @param asset - URL strings or an objects representing the resource.
* @param [opts] - Options
*/
add(asset: string | any | String[] | object[], opts?: any): any;
/**
* Return asset by URL
* @example
* const asset = assetManager.get('http://img.jpg');
* @param src - URL of the asset
*/
get(src: string): any;
/**
* Return the global collection, containing all the assets
*/
getAll(): any;
/**
* Return the visible collection, which contains assets actually rendered
*/
getAllVisible(): any;
/**
* Remove asset
* @example
* const removed = assetManager.remove('http://img.jpg');
* // or by passing the Asset
* const asset = assetManager.get('http://img.jpg');
* assetManager.remove(asset);
*/
remove(): any;
/**
* Store assets data to the selected storage
* @example
* var assets = assetManager.store();
* @param noStore - If true, won't store
* @returns Data to store
*/
store(noStore: boolean): any;
/**
* Load data from the passed object.
* The fetched data will be added to the collection.
* @example
* var assets = assetManager.load({
* assets: [...]
* })
* @param data - Object of data to load
* @returns Loaded assets
*/
load(data: any): any;
/**
* Return the Asset Manager Container
*/
getContainer(): HTMLElement;
/**
* Render assets
* @example
* // Render all assets
* assetManager.render();
*
* // Render some of the assets
* const assets = assetManager.getAll();
* assetManager.render(assets.filter(
* asset => asset.get('category') == 'cats'
* ));
* @param assets - Assets to render, without the argument will render all global assets
*/
render(assets: any[]): HTMLElement;
}
interface AssetOptions {
/**
* Asset type, eg. 'image'.
*/
type: string;
/**
* Asset URL, eg. 'https://.../image.png'.
*/
src: string;
}
interface Asset extends Backbone.Model<AssetOptions> {
/**
* Get asset type.
* @example
* // Asset: { src: 'https://.../image.png', type: 'image' }
* asset.getType(); // -> 'image'
*/
getType(): string;
/**
* Get asset URL.
* @example
* // Asset: { src: 'https://.../image.png' }
* asset.getSrc(); // -> 'https://.../image.png'
*/
getSrc(): string;
/**
* Get filename of the asset (based on `src`).
* @example
* // Asset: { src: 'https://.../image.png' }
* asset.getFilename(); // -> 'image.png'
* // Asset: { src: 'https://.../image' }
* asset.getFilename(); // -> 'image'
*/
getFilename(): string;
/**
* Get extension of the asset (based on `src`).
* @example
* // Asset: { src: 'https://.../image.png' }
* asset.getExtension(); // -> 'png'
* // Asset: { src: 'https://.../image' }
* asset.getExtension(); // -> ''
*/
getExtension(): string;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/block_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* blockManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('block:add', (block) => { ... });
*
* // Use the API
* const blockManager = editor.BlockManager;
* blockManager.add(...);
* ```
*
* ## Available Events
* * `block:add` - Block added. The [Block] is passed as an argument to the callback.
* * `block:remove` - Block removed. The [Block] is passed as an argument to the callback.
* * `block:update` - Block updated. The [Block] and the object containing changes are passed as arguments to the callback.
* * `block:drag:start` - Started dragging block, the [Block] is passed as an argument.
* * `block:drag` - Dragging block, the [Block] is passed as an argument.
* * `block:drag:stop` - Dragging of the block is stopped. The dropped [Component] (if dropped successfully) and the [Block] are passed as arguments.
* * `block` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.
*
* ## Methods
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [getAllVisible](#getallvisible)
* * [remove](#remove)
* * [getConfig](#getconfig)
* * [getCategories](#getcategories)
* * [getContainer](#getcontainer)
* * [render](#render)
*
* [Block]: block.html
* [Component]: component.html
*/
interface BlockManager {
/**
* Get configuration object
*/
getConfig(): BlockManagerConfig;
/**
* Add new block.
* @example
* blockManager.add('h1-block', {
* label: 'Heading',
* content: '<h1>Put your title here</h1>',
* category: 'Basic',
* attributes: {
* title: 'Insert h1 block'
* }
* });
* @param id - Block ID
*/
add(id: string, block : BlockOptions): any;
/**
* Get the block by id.
* @example
* const block = blockManager.get('h1-block');
* console.log(JSON.stringify(block));
* // {label: 'Heading', content: '<h1>Put your ...', ...}
* @param id - Block id
*/
get(id: string): any;
/**
* Return all blocks.
* @example
* const blocks = blockManager.getAll();
* console.log(JSON.stringify(blocks));
* // [{label: 'Heading', content: '<h1>Put your ...'}, ...]
*/
getAll(): any;
/**
* Return the visible collection, which containes blocks actually rendered
*/
getAllVisible(): any;
/**
* Remove block.
* @example
* const removed = blockManager.remove('BLOCK_ID');
* // or by passing the Block
* const block = blockManager.get('BLOCK_ID');
* blockManager.remove(block);
*/
remove(): any;
/**
* Get all available categories.
* It's possible to add categories only within blocks via 'add()' method
*/
getCategories(): any[] | Backbone.Collection<Backbone.Model>;
/**
* Return the Blocks container element
*/
getContainer(): HTMLElement;
/**
* Render blocks
* @example
* // Render all blocks (inside the global collection)
* blockManager.render();
*
* // Render new set of blocks
* const blocks = blockManager.getAll();
* const filtered = blocks.filter(block => block.get('category') == 'sections')
*
* blockManager.render(filtered);
* // Or a new set from an array
* blockManager.render([
* {label: 'Label text', content: '<div>Content</div>'}
* ]);
*
* // Back to blocks from the global collection
* blockManager.render();
*
* // You can also render your blocks outside of the main block container
* const newBlocksEl = blockManager.render(filtered, { external: true });
* document.getElementById('some-id').appendChild(newBlocksEl);
* @param blocks - Blocks to render, without the argument will render all global blocks
* @param [opts = {}] - Options
* @param [opts.external] - Render blocks in a new container (HTMLElement will be returned)
* @param [opts.ignoreCategories] - Render blocks without categories
* @returns Rendered element
*/
render(blocks: any[], opts?: {
external?: boolean;
ignoreCategories?: boolean;
}): HTMLElement;
}
interface BlockOptions {
/**
* Block label, eg. `My block`
*/
label: string;
/**
* The content of the block. Might be an HTML string or a [Component Defintion](/modules/Components.html#component-definition)
*/
content: string | any;
/**
* HTML string for the media/icon of the block, eg. `<svg ...`, `<img ...`, etc.
* @defaultValue ''
*/
media?: string;
/**
* Block category, eg. `Basic blocks`
* @defaultValue ''
*/
category?: string;
/**
* If true, triggers the `active` event on the dropped component.
*/
activate?: boolean;
/**
* If true, the dropped component will be selected.
*/
select?: boolean;
/**
* If true, all IDs of dropped components and their styles will be changed.
*/
resetId?: boolean;
/**
* Disable the block from being interacted
*/
disable?: boolean;
/**
* Custom behavior on click, eg. `(block, editor) => editor.getWrapper().append(block.get('content'))`
*/
onClick?: (...params: any[]) => any;
}
interface Block extends Backbone.Model<BlockOptions> {
/**
* Get block id
*/
getId(): string;
/**
* Get block label
*/
getLabel(): string;
/**
* Get block media
*/
getMedia(): string;
/**
* Get block content
* @returns Component definition | HTML string
*/
getContent(): any | string | (object | String)[];
/**
* Get block category label
*/
getCategoryLabel(): string;
self(): Block;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/commands/config/config.js)
* ```js
* const editor = grapesjs.init({
* commands: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('run', () => { ... });
*
* // Use the API
* const commands = editor.Commands;
* commands.add(...);
* ```
*
* * ## Available Events
* * `run:{commandName}` - Triggered when some command is called to run (eg. editor.runCommand('preview'))
* * `stop:{commandName}` - Triggered when some command is called to stop (eg. editor.stopCommand('preview'))
* * `run:{commandName}:before` - Triggered before the command is called
* * `stop:{commandName}:before` - Triggered before the command is called to stop
* * `abort:{commandName}` - Triggered when the command execution is aborted (`editor.on(`run:preview:before`, opts => opts.abort = 1);`)
* * `run` - Triggered on run of any command. The id and the result are passed as arguments to the callback
* * `stop` - Triggered on stop of any command. The id and the result are passed as arguments to the callback
*
* ## Methods
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [extend](#extend)
* * [has](#has)
* * [run](#run)
* * [stop](#stop)
* * [isActive](#isactive)
* * [getActive](#getactive)
*/
interface Commands {
/**
* Add new command to the collection
* @example
* commands.add('myCommand', {
* run(editor, sender) {
* alert('Hello world!');
* },
* stop(editor, sender) {
* },
* });
* // As a function
* commands.add('myCommand2', editor => { ... });
*/
add(id : string, command : (editor : Editor) => void | {
run: (editor: Editor, sender? : any) => void;
stop: (editor: Editor, sender? : any) => void;
}) : void
/**
* Get command by ID
* @example
* var myCommand = commands.get('myCommand');
* myCommand.run();
* @param id - Command's ID
* @returns Object representing the command
*/
get(id: string): any;
/**
* Extend the command. The command to extend should be defined as an object
* @example
* commands.extend('old-command', {
* someInnerFunction() {
* // ...
* }
* });
* @param id - Command's ID
* @param Object - with the new command functions
*/
extend(id: string, Object: any): Commands;
/**
* Check if command exists
* @param id - Command's ID
*/
has(id: string): boolean;
/**
* Get an object containing all the commands
*/
getAll(): any;
/**
* Execute the command
* @example
* commands.run('myCommand', { someOption: 1 });
* @param id - Command ID
* @param [options = {}] - Options
* @returns The return is defined by the command
*/
run(id: string, options?: any): any;
/**
* Stop the command
* @example
* commands.stop('myCommand', { someOption: 1 });
* @param id - Command ID
* @param [options = {}] - Options
* @returns The return is defined by the command
*/
stop(id: string, options?: any): any;
/**
* Check if the command is active. You activate commands with `run`
* and disable them with `stop`. If the command was created without `stop`
* method it can't be registered as active
* @example
* const cId = 'some-command';
* commands.run(cId);
* commands.isActive(cId);
* // -> true
* commands.stop(cId);
* commands.isActive(cId);
* // -> false
* @param id - Command id
*/
isActive(id: string): boolean;
/**
* Get all active commands
* @example
* console.log(commands.getActive());
* // -> { someCommand: itsLastReturn, anotherOne: ... };
*/
getActive(): any;
}
interface AddComponentOptions {
isComponent?: (el : HTMLElement) => boolean | ComponentOptions,
model?: ComponentDefinition
view?: ComponentViewDefinition
}
interface ComponentDefinition {
defaults?: ComponentOptions
init?: (this: Component) => void
handlePropChange?: (this: Component) => void
handleAttrChange?: (this: Component) => void
handleTitleChange?: (this: Component) => void
}
interface ComponentViewDefinition {
tagName : string,
events: Record<string, string>
init?: (options: {model: Component}) => void
removed?: () => void
onRender?: (options: {el : HTMLElement, model: Component}) => void
}
/**
* With this module is possible to manage components inside the canvas. You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/dom_components/config/config.js)
* ```js
* const editor = grapesjs.init({
* domComponents: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('component:create', () => { ... });
*
* // Use the API
* const cmp = editor.Components;
* cmp.addType(...);
* ```
*
* ## Available Events
* * `component:create` - Component is created (only the model, is not yet mounted in the canvas), called after the init() method
* * `component:mount` - Component is mounted to an element and rendered in canvas
* * `component:add` - Triggered when a new component is added to the editor, the model is passed as an argument to the callback
* * `component:remove` - Triggered when a component is removed, the model is passed as an argument to the callback
* * `component:remove:before` - Triggered before the remove of the component, the model, remove function (if aborted via options, with this function you can complete the remove) and options (use options.abort = true to prevent remove), are passed as arguments to the callback
* * `component:clone` - Triggered when a component is cloned, the new model is passed as an argument to the callback
* * `component:update` - Triggered when a component is updated (moved, styled, etc.), the model is passed as an argument to the callback
* * `component:update:{propertyName}` - Listen any property change, the model is passed as an argument to the callback
* * `component:styleUpdate` - Triggered when the style of the component is updated, the model is passed as an argument to the callback
* * `component:styleUpdate:{propertyName}` - Listen for a specific style property change, the model is passed as an argument to the callback
* * `component:selected` - New component selected, the selected model is passed as an argument to the callback
* * `component:deselected` - Component deselected, the deselected model is passed as an argument to the callback
* * `component:toggled` - Component selection changed, toggled model is passed as an argument to the callback
* * `component:type:add` - New component type added, the new type is passed as an argument to the callback
* * `component:type:update` - Component type updated, the updated type is passed as an argument to the callback
* * `component:drag:start` - Component drag started. Passed an object, to the callback, containing the `target` (component to drag), `parent` (parent of the component) and `index` (component index in the parent)
* * `component:drag` - During component drag. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the current pointer
* * `component:drag:end` - Component drag ended. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the final pointer
*
* ## Methods
* * [getWrapper](#getwrapper)
* * [getComponents](#getcomponents)
* * [addComponent](#addcomponent)
* * [clear](#clear)
* * [load](#load)
* * [store](#store)
* * [addType](#addtype)
* * [getType](#gettype)
* * [getTypes](#gettypes)
* * [render](#render)
*/
interface Components {
/**
* Load components from the passed object, if the object is empty will try to fetch them
* autonomously from the selected storage
* The fetched data will be added to the collection
* @param data - Object of data to load
* @returns Loaded data
*/
load(data: any): any;
/**
* Store components on the selected storage
* @param noStore - If true, won't store
* @returns Data to store
*/
store(noStore: boolean): any;
/**
* Returns root component inside the canvas. Something like `<body>` inside HTML page
* The wrapper doesn't differ from the original Component Model
* @example
* // Change background of the wrapper and set some attribute
* var wrapper = cmp.getWrapper();
* wrapper.set('style', {'background-color': 'red'});
* wrapper.set('attributes', {'title': 'Hello!'});
* @returns Root Component
*/
getWrapper(): Component;
/**
* Returns wrapper's children collection. Once you have the collection you can
* add other Components(Models) inside. Each component can have several nested
* components inside and you can nest them as more as you wish.
* @example
* // Let's add some component
* var wrapperChildren = cmp.getComponents();
* var comp1 = wrapperChildren.add({
* style: { 'background-color': 'red'}
* });
* var comp2 = wrapperChildren.add({
* tagName: 'span',
* attributes: { title: 'Hello!'}
* });
* // Now let's add an other one inside first component
* // First we have to get the collection inside. Each
* // component has 'components' property
* var comp1Children = comp1.get('components');
* // Procede as before. You could also add multiple objects
* comp1Children.add([
* { style: { 'background-color': 'blue'}},
* { style: { height: '100px', width: '100px'}}
* ]);
* // Remove comp2
* wrapperChildren.remove(comp2);
* @returns Collection of components
*/
getComponents(): Components;
/**
* Add new components to the wrapper's children. It's the same
* as 'cmp.getComponents().add(...)'
* @example
* // Example of a new component with some extra property
* var comp1 = cmp.addComponent({
* tagName: 'div',
* removable: true, // Can't remove it
* draggable: true, // Can't move it
* copyable: true, // Disable copy/past
* content: 'Content text', // Text inside component
* style: { color: 'red'},
* attributes: { title: 'here' }
* });
* @param component - Component/s to add
* @param [component.tagName = 'div'] - Tag name
* @param [component.type = ''] - Type of the component. Available: ''(default), 'text', 'image'
* @param [component.removable = true] - If component is removable
* @param [component.draggable = true] - If is possible to move the component around the structure
* @param [component.droppable = true] - If is possible to drop inside other components
* @param [component.badgable = true] - If the badge is visible when the component is selected
* @param [component.stylable = true] - If is possible to style component
* @param [component.copyable = true] - If is possible to copy&paste the component
* @param [component.content = ''] - String inside component
* @param [component.style = {}] - Style object
* @param [component.attributes = {}] - Attribute object
* @param opt - the options object to be used by the [Components.add]{@link getComponents} method
* @returns Component/s added
*/
addComponent(component: {
tagName?: string;
type?: string;
removable?: boolean;
draggable?: boolean;
droppable?: boolean;
badgable?: boolean;
stylable?: boolean;
copyable?: boolean;
content?: string;
style?: any;
attributes?: any;
}, opt: any): Component;
/**
* Render and returns wrapper element with all components inside.
* Once the wrapper is rendered, and it's what happens when you init the editor,
* the all new components will be added automatically and property changes are all
* updated immediately
*/
render(): HTMLElement;
/**
* Remove all components
*/
clear(): Components;
/**
* Add new component type.
* Read more about this in [Define New Component](https://grapesjs.com/docs/modules/Components.html#define-new-component)
* @param type - Component ID
* @param methods - Component methods
*/
addType(type: string, methods: AddComponentOptions): Components;
/**
* Get component type.
* Read more about this in [Define New Component](https://grapesjs.com/docs/modules/Components.html#define-new-component)
* @param type - Component ID
* @returns Component type definition, eg. `{ model: ..., view: ... }`
*/
getType(type: string): any;
/**
* Remove component type
* @param type - Component ID
* @returns Removed component type, undefined otherwise
*/
removeType(type: string): any | undefined;
/**
* Return the array of all types
*/
getTypes(): any[];
}
interface ComponentOptions {
/**
* Component type, eg. `text`, `image`, `video`, etc.
* @defaultValue ''
*/
type?: string;
/**
* HTML tag of the component, eg. `span`. Default: `div`
* @defaultValue 'div'
*/
tagName?: string;
/**
* Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}`
* @defaultValue {}
*/
attributes?: Record<string, any>;
/**
* Name of the component. Will be used, for example, in Layers and badges
* @defaultValue ''
*/
name?: string;
/**
* When `true` the component is removable from the canvas, default: `true`
* @defaultValue true
*/
removable?: boolean;
/**
* 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. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drag is possible. Default: `true`
* @defaultValue true
*/
draggable?: boolean | string | ((...params: any[]) => any);
/**
* Indicates if it's possible to drop other components inside. You can use
a query string as with `draggable`. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drop is possible. Default: `true`
* @defaultValue true
*/
droppable?: boolean | string | ((...params: any[]) => any);
/**
* Set to false if you don't want to see the badge (with the name) over the component. Default: `true`
* @defaultValue true
*/
badgable?: boolean;
/**
* 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`
* @defaultValue true
*/
stylable?: boolean | String[];
///**
// * Indicate an array of style properties to show up which has been marked as `toRequire`. Default: `[]`
// * @defaultValue []
// */
//`stylable-require`?: String[];
/**
* Indicate an array of style properties which should be hidden from the style manager. Default: `[]`
* @defaultValue []
*/
unstylable?: String[];
/**
* It can be highlighted with 'dotted' borders if true. Default: `true`
* @defaultValue true
*/
highlightable?: boolean;
/**
* True if it's possible to clone the component. Default: `true`
* @defaultValue true
*/
copyable?: boolean;
/**
* 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`
*/
resizable?: boolean;
/**
* Allow to edit the content of the component (used on Text components). Default: `false`
*/
editable?: boolean;
/**
* Set to `false` if you need to hide the component inside Layers. Default: `true`
* @defaultValue true
*/
layerable?: boolean;
/**
* Allow component to be selected when clicked. Default: `true`
* @defaultValue true
*/
selectable?: boolean;
/**
* Shows a highlight outline when hovering on the element if `true`. Default: `true`
* @defaultValue true
*/
hoverable?: boolean;
/**
* This property is used by the HTML exporter as void elements don't have closing tags, eg. `<br/>`, `<hr/>`, etc. Default: `false`
*/
void?: boolean;
/**
* Component default style, eg. `{ width: '100px', height: '100px', 'background-color': 'red' }`
* @defaultValue {}
*/
style?: any;
/**
* Component related styles, eg. `.my-component-class { color: red }`
* @defaultValue ''
*/
styles?: string;
/**
* Content of the component (not escaped) which will be appended before children rendering. Default: `''`
* @defaultValue ''
*/
content?: string;
/**
* Component's icon, this string will be inserted before the name (in Layers and badge), eg. it can be an HTML string '<i class="fa fa-square-o"></i>'. Default: `''`
* @defaultValue ''
*/
icon?: string;
/**
* Component's javascript. More about it [here](/modules/Components-js.html). Default: `''`
* @defaultValue ''
*/
script?: string | ((...params: any[]) => any);
///**
// * You can specify javascript available only in export functions (eg. when you get the HTML).
//If this property is defined it will overwrite the `script` one (in export functions). Default: `''`
// * @defaultValue ''
// */
//script-export?: string | ((...params: any[]) => any);
/**
* Component's traits. More about it [here](/modules/Traits.html). Default: `['id', 'title']`
* @defaultValue ''
*/
traits?: TraitOptions[] | String[] | Backbone.Collection<TraitOptions>;
/**
* 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: `[]`
* @defaultValue []
*/
propagate?: String[];
/**
* 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 `core:component-exit` (select parent component, added if there is one), `tlb-move` (added if `draggable`) , `tlb-clone` (added if `copyable`), `tlb-delete` (added if `removable`).
*/
toolbar?: object[];
///**
// * Children components. Default: `null`
// */
components?: Backbone.Collection<Component>;
[key: string]: any
}
/**
* The Component object represents a single node of our template structure, so when you update its properties the changes are
* immediately 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'
* ```
*
* [Component]: component.html
*/
interface Component extends Backbone.Model<ComponentOptions> {
view?: ComponentView
/**
* Hook method, called once the model is created
*/
init(): void;
/**
* Hook method, called when the model has been updated (eg. updated some model's property)
* @param property - Property name, if triggered after some property update
* @param value - Property value, if triggered after some property update
* @param previous - Property previous value, if triggered after some property update
*/
updated(property: string, value: any, previous: any): void;
/**
* Hook method, called once the model has been removed
*/
removed(): void;
/**
* Check component's type
* @example
* component.is('image')
* // -> false
* @param type - Component type
*/
is(type: string): boolean;
/**
* Return all the propeties
*/
props(): ComponentOptions;
/**
* Get the index of the component in the parent collection.
*/
index(): number;
/**
* Change the drag mode of the component.
* To get more about this feature read: https://github.com/artf/grapesjs/issues/1936
* @param value - Drag mode, options: 'absolute' | 'translate'
*/
setDragMode(value: string): this;
/**
* Find inner components by query string.
* **ATTENTION**: this method works only with already rendered component
* @example
* component.find('div > .class');
* // -> [Component, Component, ...]
* @param query - Query string
* @returns Array of components
*/
find(query: string): Component[];
/**
* Find all inner components by component type.
* The advantage of this method over `find` is that you can use it
* also before rendering the component
* @example
* const allImages = component.findType('image');
* console.log(allImages[0]) // prints the first found component
* @param type - Component type
*/
findType(type: string): Component[];
/**
* Find the closest parent component by query string.
* **ATTENTION**: this method works only with already rendered component
* @example
* component.closest('div.some-class');
* // -> Component
* @param query - Query string
*/
closest(query: string): Component;
/**
* Find the closest parent component by its type.
* The advantage of this method over `closest` is that you can use it
* also before rendering the component
* @example
* const Section = component.closestType('section');
* console.log(Section);
* @param type - Component type
* @returns Found component, otherwise `undefined`
*/
closestType(type: string): Component;
/**
* The method returns a Boolean value indicating whether the passed
* component is a descendant of a given component
* @param component - Component to check
*/
contains(component: Component): boolean;
/**
* Replace a component with another one
* @example
* component.replaceWith('<div>Some new content</div>');
* // -> Component
* @param el - Component or HTML string
* @returns New added component/s
*/
replaceWith(el: string | Component): Component | Component[];
/**
* Update attributes of the component
* @example
* component.setAttributes({ id: 'test', 'data-key': 'value' });
* @param attrs - Key value attributes
* @param options - Options for the model update
*/
setAttributes(attrs: any, options: any): this;
/**
* Add attributes to the component
* @example
* component.addAttributes({ 'data-key': 'value' });
* @param attrs - Key value attributes
* @param options - Options for the model update
*/
addAttributes(attrs: any, options: any): this;
/**
* Remove attributes from the component
* @example
* component.removeAttributes('some-attr');
* component.removeAttributes(['some-attr1', 'some-attr2']);
* @param attrs - Array of attributes to remove
* @param options - Options for the model update
*/
removeAttributes(attrs: string | String[], options: any): this;
/**
* Get the style of the component
*/
getStyle(): any;
/**
* Set the style on the component
* @example
* component.setStyle({ color: 'red' });
* @param prop - Key value style object
*/
setStyle(prop: any): any;
/**
* Return all component's attributes
*/
getAttributes(): Record<string, any>;
/**
* Add classes
* @example
* model.addClass('class1');
* model.addClass('class1 class2');
* model.addClass(['class1', 'class2']);
* // -> [SelectorObject, ...]
* @param classes - Array or string of classes
* @returns Array of added selectors
*/
addClass(classes: String[] | string): any[];
/**
* Set classes (resets current collection)
* @example
* model.setClass('class1');
* model.setClass('class1 class2');
* model.setClass(['class1', 'class2']);
* // -> [SelectorObject, ...]
* @param classes - Array or string of classes
* @returns Array of added selectors
*/
setClass(classes: String[] | string): any[];
/**
* Remove classes
* @example
* model.removeClass('class1');
* model.removeClass('class1 class2');
* model.removeClass(['class1', 'class2']);
* // -> [SelectorObject, ...]
* @param classes - Array or string of classes
* @returns Array of removed selectors
*/
removeClass(classes: String[] | string): any[];
/**
* Returns component's classes as an array of strings
*/
getClasses(): any[];
/**
* Add new component children
* @example
* someComponent.get('components').length // -> 0
* const videoComponent = someComponent.append('<video></video><div></div>')[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]);
* // append at specific index (eg. at the beginning)
* someComponent.append(otherComponent, { at: 0 });
* @param components - Component to add
* @param [opts = {}] - Options for the append action
* @returns Array of appended components
*/
append(components: Component | string, opts?: any): any[];
/**
* Set new collection if `components` are provided, otherwise the
* current collection is returned
* @example
* // Set new collection
* component.components('<span></span><div></div>');
* // Get current collection
* const collection = component.components();
* console.log(collection.length);
* // -> 2
* @param [components] - Component Definitions or HTML string
* @param [opts = {}] - Options, same as in `Component.append()`
*/
components(components?: Component | string, opts?: any): Backbone.Collection<Component>;
/**
* If exists, returns the child component at specific index.
* @example
* // Return first child
* component.getChildAt(0);
* // Return second child
* component.getChildAt(1);
* @param index - Index of the component to return
*/
getChildAt(index: number): any;
/**
* If exists, returns the last child component.
* @example
* const lastChild = component.getLastChild();
*/
getLastChild(): any;
/**
* Remove all inner components
* * @return {this}
*/
empty(): void;
/**
* Get the parent component, if exists
* @example
* component.parent();
* // -> Component
*/
parent(): Component | null;
/**
* Get traits.
* @example
* const traits = component.getTraits();
* console.log(traits);
* // [Trait, Trait, Trait, ...]
*/
getTraits(): Trait[];
/**
* Replace current collection of traits with a new one.
* @example
* const traits = component.setTraits([{ type: 'checkbox', name: 'disabled'}, ...]);
* console.log(traits);
* // [Trait, ...]
* @param traits - Array of trait definitions
*/
setTraits(traits: object[]): Trait[];
/**
* Get the trait by id/name.
* @example
* const traitTitle = component.getTrait('title');
* traitTitle && traitTitle.set('label', 'New label');
* @param id - The `id` or `name` of the trait
* @returns Trait getModelToStyle
*/
getTrait(id: string): Trait | null;
/**
* Update a trait.
* @example
* component.updateTrait('title', {
* type: 'select',
* options: [ 'Option 1', 'Option 2' ],
* });
* @param id - The `id` or `name` of the trait
* @param props - Object with the props to update
*/
updateTrait(id: string, props: any): this;
/**
* Get the trait position index by id/name. Useful in case you want to
* replace some trait, at runtime, with something else.
* @example
* const traitTitle = component.getTraitIndex('title');
* console.log(traitTitle); // 1
* @param id - The `id` or `name` of the trait
* @returns Index position of the current trait
*/
getTraitIndex(id: string): number;
/**
* Remove trait/s by id/s.
* @example
* component.removeTrait('title');
* component.removeTrait(['title', 'id']);
* @param id - The `id`/`name` of the trait (or an array)
* @returns Array of removed traits
*/
removeTrait(id: string | String[]): Trait[];
/**
* Add new trait/s.
* @example
* component.addTrait('title', { at: 1 }); // Add title trait (`at` option is the position index)
* component.addTrait({
* type: 'checkbox',
* name: 'disabled',
* });
* component.addTrait(['title', {...}, ...]);
* @param trait - Trait to add (or an array of traits)
* @param opts - Options for the add
* @returns Array of added traits
*/
addTrait(trait: string | any | (String | object)[], opts: Record<string, any>): Trait[];
/**
* Get the name of the component
*/
getName(): string;
/**
* Get the icon string
*/
getIcon(): string;
/**
* Return HTML string of the component
* @example
* // Simple HTML return
* component.set({ tagName: 'span' });
* component.setAttributes({ title: 'Hello' });
* component.toHTML();
* // -> <span title="Hello"></span>
*
* // Custom attributes
* component.toHTML({ attributes: { 'data-test': 'Hello' } });
* // -> <span data-test="Hello"></span>
*
* // Custom dynamic attributes
* component.toHTML({
* attributes(component, attributes) {
* if (component.get('tagName') == 'span') {
* attributes.title = 'Custom attribute';
* }
* return attributes;
* },
* });
* // -> <span title="Custom attribute"></span>
* @param [opts = {}] - Options
* @param [opts.tag] - Custom tagName
* @param [opts.attributes = null] - You can pass an object of custom attributes to replace with the current ones or you can even pass a function to generate attributes dynamically.
* @param [opts.withProps] - Include component properties as `data-gjs-*` attributes. This allows you to have re-importable HTML.
* @param [opts.altQuoteAttr] - In case the attribute value contains a `"` char, instead of escaping it (`attr="value &quot;"`), the attribute will be quoted using single quotes (`attr='value "'`).
* @returns HTML string
*/
toHTML(opts?: {
tag?: string;
attributes?: any | ((...params: any[]) => any);
withProps?: boolean;
altQuoteAttr?: boolean;
}): string;
/**
* Get inner HTML of the component
* @param [opts = {}] - Same options of `toHTML`
* @returns HTML string
*/
getInnerHTML(opts?: any): string;
/**
* Return an object containing only changed props
*/
getChangedProps(): void;
/**
* Get block id
*/
getId(): string;
/**
* Set new id on the component
*/
setId(id: string): this;
/**
* Get the DOM element of the component.
* This works only if the component is already rendered
* @param frame - Specific frame from which taking the element
*/
getEl(frame?: Frame): HTMLElement;
/**
* Get the View of the component.
* This works only if the component is already rendered
* @param frame - Get View of a specific frame
*/
getView(frame?: Frame): ComponentView;
/**
* Execute callback function on itself and all inner components
* @example
* component.onAll(component => {
* // do something with component
* })
* @param clb - Callback function, the model is passed as an argument
*/
onAll(clb: (...params: any[]) => any): this;
/**
* Remove the component
*/
remove(): this;
/**
* Move the component to another destination component
* @example
* // Move the selected component on top of the wrapper
* const dest = editor.getWrapper();
* editor.getSelected().move(dest, { at: 0 });
* @param component - Destination component (so the current one will be appended as a child)
* @param opts - Options for the append action
*/
move(component: Component, opts: any): this;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/panels/config/config.js)
* ```js
* const editor = grapesjs.init({
* panels: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const panelManager = editor.Panels;
* ```
*
* * [addPanel](#addpanel)
* * [addButton](#addbutton)
* * [getButton](#getbutton)
* * [getPanel](#getpanel)
* * [getPanels](#getpanels)
* * [getPanelsEl](#getpanelsel)
* * [removePanel](#removepanel)
* * [removeButton](#removebutton)
*/
interface Panels {
/**
* Returns the collection of panels
* @returns Collection of panel
*/
getPanels(): Backbone.Collection<Panel>;
/**
* Returns panels element
*/
getPanelsEl(): HTMLElement;
/**
* Add new panel to the collection
* @example
* var newPanel = panelManager.addPanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
* @param panel - Object with right properties or an instance of Panel
* @returns Added panel. Useful in case passed argument was an Object
*/
addPanel(panel: any | Panel): Panel;
/**
* Remove a panel from the collection
* @example
* const newPanel = panelManager.removePanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
*
* const newPanel = panelManager.removePanel('myNewPanel');
* @param panel - Object with right properties or an instance of Panel or Painel id
* @returns Removed panel. Useful in case passed argument was an Object
*/
removePanel(panel: any | Panel | string): Panel;
/**
* Get panel by ID
* @example
* var myPanel = panelManager.getPanel('myNewPanel');
* @param id - Id string
*/
getPanel(id: string): Panel | null;
/**
* Add button to the panel
* @example
* var newButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
* // It's also possible to pass the command as an object
* // with .run and .stop methods
* ...
* command: {
* run: function(editor) {
* ...
* },
* stop: function(editor) {
* ...
* }
* },
* // Or simply like a which will be evaluated as a single .run command
* ...
* command: function(editor) {
* ...
* }
* @param panelId - Panel's ID
* @param button - Button object or instance of Button
* @returns Added button. Useful in case passed button was an Object
*/
addButton(panelId: string, button: ButtonOptions | Button): Button | null;
/**
* Remove button from the panel
* @example
* const removedButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
*
* const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton');
* @param panelId - Panel's ID
* @param buttonId - Button's ID
* @returns Removed button.
*/
removeButton(panelId: string, buttonId: string): Button | null;
/**
* Get button from the panel
* @example
* var button = panelManager.getButton('myPanel','myButton');
* @param panelId - Panel's ID
* @param id - Button's ID
*/
getButton(panelId: string, id: string): Button | null;
}
/**
* With Style Manager you build categories (called sectors) of CSS properties which could be used to customize the style of components.
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/style_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* styleManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('style:sector:add', (sector) => { ... });
*
* // Use the API
* const styleManager = editor.StyleManager;
* styleManager.addSector(...);
* ```
* ## Available Events
* * `style:sector:add` - Sector added. The [Sector] is passed as an argument to the callback.
* * `style:sector:remove` - Sector removed. The [Sector] is passed as an argument to the callback.
* * `style:sector:update` - Sector updated. The [Sector] and the object containing changes are passed as arguments to the callback.
* * `style:property:add` - Property added. The [Property] is passed as an argument to the callback.
* * `style:property:remove` - Property removed. The [Property] is passed as an argument to the callback.
* * `style:property:update` - Property updated. The [Property] and the object containing changes are passed as arguments to the callback.
* * `style:target` - Target selection changed. The target (or `null` in case the target is deselected) is passed as an argument to the callback.
* <!--
* * `styleManager:update:target` - The target (Component or CSSRule) is changed
* * `styleManager:change` - Triggered on style property change from new selected component, the view of the property is passed as an argument to the callback
* * `styleManager:change:{propertyName}` - As above but for a specific style property
* -->
*
* ## Methods
* * [getConfig](#getconfig)
* * [addSector](#addsector)
* * [getSector](#getsector)
* * [getSectors](#getsectors)
* * [removeSector](#removesector)
* * [addProperty](#addproperty)
* * [getProperty](#getproperty)
* * [getProperties](#getproperties)
* * [removeProperty](#removeproperty)
* * [select](#select)
* * [getSelected](#getselected)
* * [getSelectedAll](#getselectedall)
* * [getSelectedParents](#getselectedparents)
* * [addStyleTargets](#addstyletargets)
* * [getBuiltIn](#getbuiltin)
* * [getBuiltInAll](#getbuiltinall)
* * [addBuiltIn](#addbuiltin)
* * [addType](#addtype)
* * [getType](#gettype)
* * [getTypes](#gettypes)
*
* [Sector]: sector.html
* [CssRule]: css_rule.html
* [Component]: component.html
* [Property]: property.html
*/
interface StyleManager {
/**
* Get configuration object
*/
getConfig(): StyleManagerConfig;
/**
* Add new sector. If the sector with the same id already exists, that one will be returned.
* @example
* const sector = styleManager.addSector('mySector',{
* name: 'My sector',
* open: true,
* properties: [{ name: 'My property'}]
* }, { at: 0 });
* // With `at: 0` we place the new sector at the beginning of the list
* @param id - Sector id
* @param sector - Sector definition. Check the [available properties](sector.html#properties)
* @param [options = {}] - Options
* @param [options.at] - Position index (by default, will be appended at the end).
*/
addSector(id: string, sector: any, options?: {
at?: number;
}): any;
/**
* Get sector by id.
* @example
* const sector = styleManager.getSector('mySector');
* @param id - Sector id
*/
getSector(id: string): any;
/**
* Get all sectors.
* @example
* const sectors = styleManager.getSectors();
* @param [opts = {}] - Options
* @param [opts.visible] - Returns only visible sectors
*/
getSectors(opts?: {
visible?: boolean;
}): any;
/**
* Remove sector by id.
* @example
* const removed = styleManager.removeSector('mySector');
* @param id - Sector id
*/
removeSector(id: string): any;
/**
* Add new property to the sector.
* @example
* const property = styleManager.addProperty('mySector', {
* label: 'Minimum height',
* property: 'min-height',
* type: 'select',
* default: '100px',
* options: [
* { id: '100px', label: '100' },
* { id: '200px', label: '200' },
* ],
* }, { at: 0 });
* @param sectorId - Sector id.
* @param property - Property definition. Check the [base available properties](property.html#properties) + others based on the `type` of your property.
* @param [opts = {}] - Options
* @param [opts.at] - Position index (by default, will be appended at the end).
*/
addProperty(sectorId: string, property: any, opts?: {
at?: number;
}): any;
/**
* Get the property.
* @example
* const property = styleManager.getProperty('mySector', 'min-height');
* @param sectorId - Sector id.
* @param id - Property id.
*/
getProperty(sectorId: string, id: string): any;
/**
* Get all properties of the sector.
* @example
* const properties = styleManager.getProperties('mySector');
* @param sectorId - Sector id.
*/
getProperties(sectorId: string): any;
/**
* Remove the property.
* @example
* const property = styleManager.removeProperty('mySector', 'min-height');
* @param sectorId - Sector id.
* @param id - Property id.
*/
removeProperty(sectorId: string, id: string): any;
/**
* Select new target.
* The target could be a Component, CSSRule, or a CSS selector string.
* @example
* // Select the first button in the current page
* const wrapperCmp = editor.Pages.getSelected().getMainComponent();
* const btnCmp = wrapperCmp.find('button')[0];
* btnCmp && styleManager.select(btnCmp);
*
* // Set as a target the CSS selector
* styleManager.select('.btn > span');
*/
select(): any;
/**
* Get the last selected target.
* By default, the Style Manager shows styles of the last selected target.
*/
getSelected(): any;
/**
* Get the array of selected targets.
*/
getSelectedAll(): any;
/**
* Get parent rules of the last selected target.
*/
getSelectedParents(): any;
/**
* Update selected targets with a custom style.
* @example
* styleManager.addStyleTargets({ color: 'red' });
* @param style - Style object
* @param [opts = {}] - Options
*/
addStyleTargets(style: any, opts?: any): void;
/**
* Return built-in property definition
* @example
* const widthPropDefinition = styleManager.getBuiltIn('width');
* @param prop - Property name.
* @returns Property definition.
*/
getBuiltIn(prop: string): any | null;
/**
* Get all the available built-in property definitions.
*/
getBuiltInAll(): any;
/**
* Add built-in property definition.
* If the property exists already, it will extend it.
* @example
* const sector = styleManager.addBuiltIn('new-property', {
* type: 'select',
* default: 'value1',
* options: [{ id: 'value1', label: 'Some label' }, ...],
* })
* @param prop - Property name.
* @param definition - Property definition.
* @returns Added property definition.
*/
addBuiltIn(prop: string, definition: any): any;
/**
* Add new property type
* @example
* styleManager.addType('my-custom-prop', {
* // Create UI
* create({ props, change }) {
* const el = document.createElement('div');
* el.innerHTML = '<input type="range" class="my-input" min="10" max="50"/>';
* const inputEl = el.querySelector('.my-input');
* inputEl.addEventListener('change', event => change({ event }));
* inputEl.addEventListener('input', event => change({ event, partial: true }));
* return el;
* },
* // Propagate UI changes up to the targets
* emit({ props, updateStyle }, { event, partial }) {
* const { value } = event.target;
* updateStyle(`${value}px`, { partial });
* },
* // Update UI (eg. when the target is changed)
* update({ value, el }) {
* el.querySelector('.my-input').value = parseInt(value, 10);
* },
* // Clean the memory from side effects if necessary (eg. global event listeners, etc.)
* destroy() {}
* })
* @param id - Type ID
* @param definition - Definition of the type.
*/
addType(id: string, definition: any): void;
/**
* Get type
* @param id - Type ID
* @returns Type definition
*/
getType(id: string): any;
/**
* Get all types
*/
getTypes(): any[];
}
interface SectorOptions {
/**
* Sector id, eg. `typography`
*/
id: string;
/**
* Sector name, eg. `Typography`
*/
name: string;
/**
* Indicates the open state.
* @defaultValue true
*/
open?: boolean;
/**
* Indicate an array of Property defintions.
* @defaultValue []
*/
properties?: Property[];
}
interface Sector extends Backbone.Model<SectorOptions> {
/**
* Get sector id
*/
getId(): string;
/**
* Get sector name
*/
getName(): string;
/**
* Update sector name.
* @param value - New sector name
*/
setName(value: string): void;
/**
* Check if the sector is open
*/
isOpen(): boolean;
/**
* Update Sector open state
*/
setOpen(value: boolean): void;
/**
* Check if the sector is visible
*/
isVisible(): boolean;
/**
* Get sector properties.
* @param [opts = {}] - Options
* @param [opts.withValue = false] - Get only properties with value
* @param [opts.withParentValue = false] - Get only properties with parent value
*/
getProperties(opts?: {
withValue?: boolean;
withParentValue?: boolean;
}): Property[];
}
interface PropertyOptions {
/**
* Property id, eg. `my-property-id`.
*/
id: string;
/**
* Related CSS property name, eg. `text-align`.
*/
property: string;
/**
* Defaul value of the property.
*/
default: string;
/**
* Label to use in UI, eg. `Text Align`.
*/
label: string;
/**
* Change callback.
\n
```js
onChange: ({ property, from, to }) => {
console.log(`Changed property`, property.getName(), { from, to });
}
```
*/
onChange?: (...params: any[]) => any;
}
interface Property<T extends PropertyOptions> extends Backbone.Model<T> {
/**
* Get property id
*/
getId(): string;
/**
* Get the property type.
* The type of the property is defined on property creation and based on its value the proper Property class is assigned.
* The default type is `base`.
*/
getType(): string;
/**
* Get name (the CSS property name).
*/
getName(): string;
/**
* Get property label.
* @param {Object} [opts={}] Options
* @param {Boolean} [opts.locale=true] Use the locale string from i18n module
*/
getLabel(opts?: {locale?: boolean}): string;
/**
* Get property value.
* @param [opts = {}] - Options
* @param [opts.noDefault = false] - Avoid returning the default value
*/
getValue(opts?: {
noDefault?: boolean;
}): string;
/**
* Check if the property has value.
* @param [opts = {}] - Options
* @param [opts.noParent = false] - Ignore the value if it comes from the parent target.
*/
hasValue(opts?: {
noParent?: boolean;
}): boolean;
/**
* Indicates if the current value is coming from a parent target (eg. another CSSRule).
*/
hasValueParent(): boolean;
/**
* Get the CSS style object of the property.
* @param {Object} [opts={}] Options
* @param {Boolean} [opts.camelCase] Return property name in camelCase.
* @example
* // In case the property is `color` with a value of `red`.
* console.log(property.getStyle());
* // { color: 'red' };
*/
getStyle(opts?: {camelCase?: boolean}): any;
/**
* Get the default value.
*/
getDefaultValue(): string;
/**
* Update the value.
* The change is also propagated to the selected targets (eg. CSS rule).
* @param value - New value
* @param [opts = {}] - Options
* @param [opts.partial = false] - If `true` the update on targets won't be considered complete (not stored in UndoManager)
* @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets.
*/
upValue(value: string, opts?: {
partial?: boolean;
noTarget?: boolean;
}): void;
/**
* Check if the sector is visible
*/
isVisible(): boolean;
/**
* Clear the value.
* The change is also propagated to the selected targets (eg. the css property is cleared).
* @param [opts = {}] - Options
* @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets.
*/
clear(opts?: {
noTarget?: boolean;
}): void;
/**
* Indicates if the current value comes directly from the selected target and so can be cleared.
*/
canClear(): boolean;
/**
* If the current property is a sub-property, this will return the parent Property.
*/
getParent(): any;
/**
* Indicates if the property is full-width in UI.
*/
isFull(): boolean;
}
interface PropertyNumberOptions extends PropertyOptions {
/**
* Array of units, eg. `['px', '%']`
*/
units: String[];
/**
* Minimum value.
*/
min: number;
/**
* Maximum value.
*/
max: number;
/**
* Step value.
*/
step: number;
}
interface PropertyNumber extends Property<PropertyNumberOptions> {
/**
* Get property units.
*/
getUnits(): String[];
/**
* Get property unit value.
*/
getUnit(): string;
/**
* Get min value.
*/
getMin(): number;
/**
* Get max value.
*/
getMax(): number;
/**
* Get step value.
*/
getStep(): number;
/**
* Update property unit value.
* The change is also propagated to the selected targets.
* @param unit - New unit value
* @param [opts = {}] - Options
* @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets.
*/
upUnit(unit: string, opts?: {
noTarget?: boolean;
}): string;
}
interface SelectOption {
id?: string
value?: string
label? : string
name?: string
}
interface PropertySelectOptions extends PropertyOptions {
/**
* Array of option definitions.
\n
```js
options: [
{ id: '100', label: 'Set 100' },
{ id: '200', label: 'Set 200' },
]
```
*/
options: SelectOption[];
}
interface PropertySelect extends Property<PropertySelectOptions> {
/**
* Get available options.
* @returns Array of options
*/
getOptions(): SelectOption[];
/**
* Get current selected option or by id.
* @param [id] - Option id.
*/
getOption(id?: string): any | null;
/**
* Update options.
* @param value - New array of options, eg. `[{ id: 'val-1', label: 'Value 1' }]`
*/
setOptions(value: SelectOption[]): void;
/**
* Add new option.
* @param value - Option object, eg. `{ id: 'val-1', label: 'Value 1' }`
*/
addOption(value: SelectOption): void;
/**
* Get the option id from the option object.
* @param option - Option object
* @returns Option id
*/
getOptionId(option: SelectOption): string;
/**
* Get option label.
* @param id - Option id or the option object
* @param [opts = {}] - Options
* @param [opts.locale = true] - Use the locale string from i18n module
* @returns Option label
*/
getOptionLabel(id: string | any, opts?: {
locale?: boolean;
}): string;
}
interface PropertyCompositeOptions extends PropertyOptions {
/**
* Array of sub properties, eg. `[{ type: 'number', property: 'margin-top' }, ...]`
*/
properties: Property[];
/**
* Indicate if the final CSS property is splitted (detached: `margin-top: X; margin-right: Y; ...`) or combined (not detached: `margin: X Y ...;`)
*/
detached?: boolean;
/**
* Value used to split property values, default `" "`.
* @defaultValue ' '
*/
separator?: string | RegExp;
/**
* Value used to join property values, default `" "`.
* @defaultValue ' '
*/
join?: string;
/**
* Custom logic for getting property values from the target style object.
\n
```js
fromStyle: (style) => {
const margins = parseMarginShorthand(style.margin);
return {
'margin-top': margins.top,
// ...
};
}
```
*/
fromStyle?: (style : Record<string, any>) => Record<string, any>;
/**
* Custom logic for creating the CSS style object to apply on selected targets.
\n
```js
toStyle: (values) => {
const top = values['margin-top'] || 0;
const right = values['margin-right'] || 0;
// ...
return {
margin: `${top} ${right} ...`,
};
}
```
*/
toStyle?: (values : Record<string, any>) => Record<string, any>;
}
interface PropertyComposite extends Property<PropertyCompositeOptions> {
/**
* Get properties.
*/
getProperties(): Property[];
/**
* Get property by id.
* @param id - Property id.
*/
getProperty(id: string): any;
/**
* Get property at index.
*/
getPropertyAt(index: number): any;
/**
* Check if the property is detached.
*/
isDetached(): boolean;
/**
* Get current values of properties.
* @example
* // In case the property is `margin` with sub properties like `margin-top`, `margin-right`, etc.
* console.log(property.getValues());
* // { 'margin-top': '10px', 'margin-right': '20px', ... };
* @param [opts = {}] - Options
* @param [opts.byName = false] - Use property names as a key instead of the id.
*/
getValues(opts?: {
byName?: boolean;
}): any;
/**
* Get property separator.
*/
getSeparator(): RegExp;
/**
* Get the join value.
*/
getJoin(): string;
}
interface Layer extends Backbone.Model {
/**
* Get layer id.
*/
getId() : string
/**
* Get layer index.
*/
getIndex() : number
/**
* Get layer values.
* @param {Object} [opts={}] Options
* @param {Boolean} [opts.camelCase] Return property names in camelCase.
*/
getValues(opts?: {camelCase? : boolean}) : any
/**
* Get layer label.
*/
getLabel() : string
/**
* Check if the layer is selected.
*/
isSelected() : boolean
/**
* Select the layer.
*/
select() : any
/**
* Remove the layer.
*/
remove() : any
/**
* Move layer to a new index.
* @param index New index
*/
move(index : number) : any
/**
* Get style object for the preview.
* @param [opts={}] Options. Same of `PropertyStack.getStyleFromLayer`
* @returns Style object
*/
getStylePreview(opts = {}) : any
/**
* Check if the property has the preview enabled for this layer.
*/
hasPreview() : boolean
}
interface PropertyStackOptions extends PropertyCompositeOptions {
/**
* Indicate if the layer should display a preview.
*/
preview?: boolean;
/**
* The separator used to split layer values.
* @defaultValue ', '
*/
layerSeparator?: string | RegExp;
/**
* Value used to join layer values.
* @defaultValue ', '
*/
layerJoin?: string;
/**
* Custom logic for creating layer labels.
\n
```js
layerLabel: (layer) => {
const values = layer.getValues();
return `A: ${values['prop-a']} B: ${values['prop-b']}`;
}
```
*/
layerLabel?: (...params: any[]) => any;
}
interface PropertyStack extends PropertyComposite<PropertyStackOptions> {
/**
* Get all available layers.
*/
getLayers(): Layer[];
/**
* Get layer by index.
* @example
* // Get the first layer
* const layerFirst = property.getLayer(0);
* // Get the last layer
* const layers = this.getLayers();
* const layerLast = property.getLayer(layers.length - 1);
* @param [index = 0] - Layer index position.
*/
getLayer(index?: number): Layer | null;
/**
* Get selected layer.
*/
getSelectedLayer(): Layer | null;
/**
* Select layer.
* Without a selected layer any update made on inner properties has no effect.
* @example
* const layer = property.getLayer(0);
* property.selectLayer(layer);
* @param layer Layer to select
*/
selectLayer(layer: Layer): void;
/**
* Select layer by index.
* @example
* property.selectLayerAt(1);
* @param index - Index of the layer to select.
*/
selectLayerAt(index: number): void;
/**
* Move layer by index.
* @example
* const layer = property.getLayer(1);
* property.moveLayer(layer, 0);
* @param index - New layer index.
*/
moveLayer(layer: Layer, index: number): void;
/**
* Add new layer to the stack.
* @example
* // Add new layer at the beginning of the stack with custom values
* property.addLayer({ 'sub-prop1': 'value1', 'sub-prop2': 'value2' }, { at: 0 });
* @param [props = {}] - Custom property values to use in a new layer.
* @param [opts = {}] - Options
* @param [opts.at] - Position index (by default the layer will be appended at the end).
*/
addLayer(props?: any, opts?: {
at?: number;
}): Layer;
/**
* Remove layer.
* @example
* const layer = property.getLayer(0);
* property.removeLayer(layer);
*/
removeLayer(layer: Layer): Layer;
/**
* Remove layer by index.
* @example
* property.removeLayerAt(0);
* @param index - Index of the layer to remove
*/
removeLayerAt(index: number): Layer | null;
/**
* Get the layer label. The label can be customized with the `layerLabel` property.
* @example
* const layer = this.getLayer(1);
* const label = this.getLayerLabel(layer);
*/
getLayerLabel(layer: Layer): string;
/**
* Get style object from the layer.
* @param [opts = {}] - Options
* @param [opts.camelCase] - Return property names in camelCase.
* @param [opts.number] - Limit the result of the number types, eg. `number: { min: -3, max: 3 }`
* @returns Style object
*/
getStyleFromLayer(layer: Layer, opts?: {
camelCase?: boolean;
number?: any;
}): any;
/**
* Get preview style object from the layer.
* If the property has `preview: false` the returned object will be empty.
* @param [opts = {}] - Options. Same of `getStyleFromLayer`
* @returns Style object
*/
getStylePreview(layer: Layer, opts?: any): any;
/**
* Get layer separator.
*/
getLayerSeparator(): RegExp;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/storage_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* storageManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('storage:start', () => { ... });
*
* // Use the API
* const storageManager = editor.StorageManager;
* storageManager.add(...);
* ```
*
* ## Available Events
* * `storage:start` - Before the storage request is started
* * `storage:start:store` - Before the store request. The object to store is passed as an argumnet (which you can edit)
* * `storage:start:load` - Before the load request. Items to load are passed as an argumnet (which you can edit)
* * `storage:load` - Triggered when something was loaded from the storage, loaded object passed as an argumnet
* * `storage:store` - Triggered when something is stored to the storage, stored object passed as an argumnet
* * `storage:end` - After the storage request is ended
* * `storage:end:store` - After the store request
* * `storage:end:load` - After the load request
* * `storage:error` - On any error on storage request, passes the error as an argument
* * `storage:error:store` - Error on store request, passes the error as an argument
* * `storage:error:load` - Error on load request, passes the error as an argument
*
* ## Methods
* * [getConfig](#getconfig)
* * [isAutosave](#isautosave)
* * [setAutosave](#setautosave)
* * [getStepsBeforeSave](#getstepsbeforesave)
* * [setStepsBeforeSave](#setstepsbeforesave)
* * [setStepsBeforeSave](#setstepsbeforesave)
* * [getStorages](#getstorages)
* * [getCurrent](#getcurrent)
* * [getCurrentStorage](#getcurrentstorage)
* * [setCurrent](#setcurrent)
* * [add](#add)
* * [get](#get)
* * [store](#store)
* * [load](#load)
*/
interface StorageManager {
/**
* Get configuration object
*/
getConfig(): StorageManagerConfig;
/**
* Checks if autosave is enabled
*/
isAutosave(): boolean;
/**
* Set autosave value
*/
setAutosave(v: boolean): this;
/**
* Returns number of steps required before trigger autosave
*/
getStepsBeforeSave(): number;
/**
* Set steps required before trigger autosave
*/
setStepsBeforeSave(v: number): this;
/**
* Add new storage
* @example
* storageManager.add('local2', {
* load: function(keys, clb, clbErr) {
* var res = {};
* for (var i = 0, len = keys.length; i < len; i++){
* var v = localStorage.getItem(keys[i]);
* if(v) res[keys[i]] = v;
* }
* clb(res); // might be called inside some async method
* // In case of errors...
* // clbErr('Went something wrong');
* },
* store: function(data, clb, clbErr) {
* for(var key in data)
* localStorage.setItem(key, data[key]);
* clb(); // might be called inside some async method
* }
* });
* @param id - Storage ID
* @param storage - Storage wrapper
* @param storage.load - Load method
* @param storage.store - Store method
*/
add(id: string, storage: {
load: (...params: any[]) => any;
store: (...params: any[]) => any;
}): this;
/**
* Returns storage by id
* @param id - Storage ID
*/
get(id: string): any | null;
/**
* Returns all storages
*/
getStorages(): any[];
/**
* Returns current storage type
*/
getCurrent(): string;
/**
* Set current storage type
* @param id - Storage ID
*/
setCurrent(id: string): this;
/**
* Store key-value resources in the current storage
* @example
* storageManager.store({item1: value1, item2: value2});
* @param data - Data in key-value format, eg. {item1: value1, item2: value2}
* @param clb - Callback function
*/
store(data: any, clb: (...params: any[]) => any): any | null;
/**
* Load resource from the current storage by keys
* @example
* storageManager.load(['item1', 'item2'], res => {
* // res -> {item1: value1, item2: value2}
* });
* storageManager.load('item1', res => {
* // res -> {item1: value1}
* });
* @param keys - Keys to load
* @param clb - Callback function
*/
load(keys: string | string[], clb: (...params: any[]) => any): void;
/**
* Get current storage
*/
getCurrentStorage(): Storage;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/device_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* deviceManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const deviceManager = editor.Devices;
* ```
* ## Available Events
* * `device:add` - Added new device. The [Device] is passed as an argument to the callback
* * `device:remove` - Device removed. The [Device] is passed as an argument to the callback
* * `device:select` - New device selected. The newly selected [Device] and the previous one, are passed as arguments to the callback
* * `device:update` - Device updated. The updated [Device] and the object containing changes are passed as arguments to the callback
* * `device` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback
*
* ## Methods
* * [add](#add)
* * [get](#get)
* * [getDevices](#getdevices)
* * [remove](#remove)
* * [select](#select)
* * [getSelected](#getselected)
*
* [Device]: device.html
*/
interface Devices {
/**
* Add new device
* @example
* const device1 = deviceManager.add({
* // Without an explicit ID, the `name` will be taken. In case of missing `name`, a random ID will be created.
* id: 'tablet',
* name: 'Tablet',
* width: '900px', // This width will be applied on the canvas frame and for the CSS media
* });
* const device2 = deviceManager.add({
* id: 'tablet2',
* name: 'Tablet 2',
* width: '800px', // This width will be applied on the canvas frame
* widthMedia: '810px', // This width that will be used for the CSS media
* height: '600px', // Height will be applied on the canvas frame
* });
* @param props - Device properties
*/
add(props: any): any;
/**
* Return device by ID
* @example
* const device = deviceManager.get('Tablet');
* console.log(JSON.stringify(device));
* // {name: 'Tablet', width: '900px'}
* @param id - ID of the device
*/
get(id: string): any;
/**
* Remove device
* @example
* const removed = deviceManager.remove('device-id');
* // or by passing the Device
* const device = deviceManager.get('device-id');
* deviceManager.remove(device);
*/
remove(): any;
/**
* Return all devices
* @example
* const devices = deviceManager.getDevices();
* console.log(JSON.stringify(devices));
* // [{name: 'Desktop', width: ''}, ...]
*/
getDevices(): any;
/**
* Change the selected device. This will update the frame in the canvas
* @example
* deviceManager.select('some-id');
* // or by passing the page
* const device = deviceManager.get('some-id');
* deviceManager.select(device);
*/
select(): void;
/**
* Get the selected device
* @example
* const selected = deviceManager.getSelected();
*/
getSelected(): any;
}
interface DeviceOptions {
/**
* Device type, eg. `Mobile`
* @defaultValue ''
*/
name?: string;
/**
* Width to set for the editor iframe, eg. '900px'
*/
width?: string;
/**
* Height to set for the editor iframe, eg. '600px'
* @defaultValue ''
*/
height?: string;
/**
* The width which will be used in media queries, If empty the width will be used
* @defaultValue ''
*/
widthMedia?: string;
/**
* Setup the order of media queries
*/
priority?: number;
}
interface Device extends Backbone.Model<DeviceOptions> {
getName() : string
getWidthMedia() : string
}
/**
* Selectors in GrapesJS are used in CSS Composer inside Rules and in Components as classes. To illustrate this concept let's take
* a look at this code:
*
* ```css
* span > #send-btn.btn{
* ...
* }
* ```
* ```html
* <span>
* <button id="send-btn" class="btn"></button>
* </span>
* ```
*
* In this scenario we get:
* * span -> selector of type `tag`
* * send-btn -> selector of type `id`
* * btn -> selector of type `class`
*
* So, for example, being `btn` the same class entity it'll be easier to refactor and track things.
*
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/selector_manager/config/config.js)
* ```js
* const editor = grapesjs.init({
* selectorManager: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('selector:add', (selector) => { ... });
*
* // Use the API
* const sm = editor.Selectors;
* sm.add(...);
* ```
*
* ## Available Events
* * `selector:add` - Selector added. The [Selector] is passed as an argument to the callback.
* * `selector:remove` - Selector removed. The [Selector] is passed as an argument to the callback.
* * `selector:update` - Selector updated. The [Selector] and the object containing changes are passed as arguments to the callback.
* * `selector:state` - States changed. An object containing all the available data about the triggered event is passed as an argument to the callback.
* * `selector` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.
*
* ## Methods
* * [getConfig](#getconfig)
* * [add](#add)
* * [get](#get)
* * [remove](#remove)
* * [getAll](#getall)
* * [setState](#setstate)
* * [getState](#getstate)
* * [getStates](#getstates)
* * [setStates](#setstates)
* * [getSelected](#getselected)
* * [addSelected](#addselected)
* * [removeSelected](#removeselected)
* * [getSelectedTargets](#getselectedtargets)
* * [setComponentFirst](#setcomponentfirst)
* * [getComponentFirst](#getcomponentfirst)
*
* [Selector]: selector.html
* [State]: state.html
* [Component]: component.html
* [CssRule]: css_rule.html
*/
interface SelectorManager {
/**
* Get configuration object
*/
getConfig(): SelectorManagerConfig;
/**
* Add a new selector to the collection if it does not already exist.
* You can pass selectors properties or string identifiers.
* @example
* const selector = selectorManager.add({ name: 'my-class', label: 'My class' });
* console.log(selector.toString()) // `.my-class`
* // Same as
* const selector = selectorManager.add('.my-class');
* console.log(selector.toString()) // `.my-class`
* @param props - Selector properties or string identifiers, eg. `{ name: 'my-class', label: 'My class' }`, `.my-cls`
* @param [opts] - Selector options
*/
add(props: any | string, opts?: SelectorOptions): any;
/**
* Get the selector by its name/type
* @example
* const selector = selectorManager.get('.my-class');
* // Get Id
* const selectorId = selectorManager.get('#my-id');
* @param name - Selector name or string identifier
*/
get(name: string): any;
/**
* Remove Selector.
* @example
* const removed = selectorManager.remove('.myclass');
* // or by passing the Selector
* selectorManager.remove(selectorManager.get('.myclass'));
*/
remove(): any;
/**
* Change the selector state
* @example
* selectorManager.setState('hover');
* @param value - State value
*/
setState(value: string): this;
/**
* Get the current selector state value
*/
getState(): string;
/**
* Get states
*/
getStates(): any;
/**
* Set a new collection of states
* @example
* const states = selectorManager.setStates([
* { name: 'hover', label: 'Hover' },
* { name: 'nth-of-type(2n)', label: 'Even/Odd' }
* ]);
* @param states - Array of new states
*/
setStates(states: object[]): any;
/**
* Get commonly selected selectors, based on all selected components.
* @example
* const selected = selectorManager.getSelected();
* console.log(selected.map(s => s.toString()))
*/
getSelected(): any;
/**
* Add new selector to all selected components.
* @example
* selectorManager.addSelected('.new-class');
* @param props - Selector properties or string identifiers, eg. `{ name: 'my-class', label: 'My class' }`, `.my-cls`
*/
addSelected(props: any | string): void;
/**
* Remove a common selector from all selected components.
* @example
* selectorManager.removeSelected('.myclass');
*/
removeSelected(): void;
/**
* Get the array of currently selected targets.
* @example
* const targetsToStyle = selectorManager.getSelectedTargets();
* console.log(targetsToStyle.map(target => target.getSelectorsString()))
*/
getSelectedTargets(): any;
/**
* Update component-first option.
* If the component-first is enabled, all the style changes will be applied on selected components (ID rules) instead
* of selectors (which would change styles on all components with those classes).
*/
setComponentFirst(value: boolean): void;
/**
* Get the value of component-first option.
*/
getComponentFirst(): boolean;
/**
* Get all selectors
*/
getAll(): any;
}
interface SelectorOptions {
/**
* Selector name, eg. `my-class`
*/
name: string;
/**
* Selector label, eg. `My Class`
*/
label: string;
/**
* Type of the selector. 1 (class) | 2 (id)
* @defaultValue 1
*/
type?: number;
/**
* If not active, it's not selectable by the Style Manager.
* @defaultValue true
*/
active?: boolean;
/**
* If true, it can't be seen by the Style Manager, but it will be rendered in the canvas and in export code.
*/
private?: boolean;
/**
* If true, it can't be removed from the attacched component.
*/
protected?: boolean;
}
interface Selector extends Backbone.Model<SelectorOptions> {
/**
* Get selector label.
* @example
* // Given such selector: { name: 'my-selector', label: 'My selector' }
* console.log(selector.getLabel());
* // -> `My selector`
*/
getLabel(): string;
/**
* Update selector label.
* @param {String} label New label
* @example
* // Given such selector: { name: 'my-selector', label: 'My selector' }
* selector.setLabel('New Label')
* console.log(selector.getLabel());
* // -> `New Label`
*/
setLabel(label: string): void;
/**
* Get selector active state.
*/
getActive(): boolean;
/**
* Update selector active state.
* @param value - New active state
*/
setActive(value: boolean): void;
}
interface StateOptions {
/**
* State name, eg. `hover`, `nth-of-type(2n)`
*/
name: string;
/**
* State label, eg. `Hover`, `Even/Odd`
*/
label: string;
}
interface State extends Backbone.Model<StateOptions> {
/**
* Get state name
*/
getName(): string;
/**
* Get state label. If label was not provided, the name will be returned.
*/
getLabel(): string;
}
/**
* This module manages CSS rules in the canvas.
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/css_composer/config/config.js)
* ```js
* const editor = grapesjs.init({
* cssComposer: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const css = editor.Css;
* ```
*
* * [addRules](#addrules)
* * [setRule](#setrule)
* * [getRule](#getrule)
* * [getRules](#getrules)
* * [remove](#remove)
* * [clear](#clear)
*
* [CssRule]: css_rule.html
*/
interface CssComposer {
/**
* Add CssRules via CSS string.
* @example
* const addedRules = css.addRules('.my-cls{ color: red } @media (max-width: 992px) { .my-cls{ color: darkred } }');
* // Check rules
* console.log(addedRules.map(rule => rule.toCSS()));
* @param css - CSS string of rules to add.
*/
addRules(css: string): any;
/**
* Add/update the CssRule.
* @example
* // Simple class-based rule
* const rule = css.setRule('.class1.class2', { color: 'red' });
* console.log(rule.toCSS()) // output: .class1.class2 { color: red }
* // With state and other mixed selector
* const rule = css.setRule('.class1.class2:hover, div#myid', { color: 'red' });
* // output: .class1.class2:hover, div#myid { color: red }
* // With media
* const rule = css.setRule('.class1:hover', { color: 'red' }, {
* atRuleType: 'media',
* atRuleParams: '(min-width: 500px)',
* });
* // output: @media (min-width: 500px) { .class1:hover { color: red } }
* @param selectors - Selector string, eg. `.myclass`
* @param style - Style properties and values
* @param [opts = {}] - Additional properties
* @param [opts.atRuleType = ''] - At-rule type, eg. `media`
* @param [opts.atRuleParams = ''] - At-rule parameters, eg. `(min-width: 500px)`
*/
setRule(selectors: string, style: any, opts?: {
atRuleType?: string;
atRuleParams?: string;
}): any;
/**
* Get the CssRule.
* @example
* const rule = css.getRule('.myclass1:hover');
* const rule2 = css.getRule('.myclass1:hover, div#myid');
* const rule3 = css.getRule('.myclass1', {
* atRuleType: 'media',
* atRuleParams: '(min-width: 500px)',
* });
* @param selectors - Selector string, eg. `.myclass:hover`
* @param [opts = {}] - Additional properties
* @param [opts.atRuleType = ''] - At-rule type, eg. `media`
* @param [opts.atRuleParams = ''] - At-rule parameters, eg. '(min-width: 500px)'
*/
getRule(selectors: string, opts?: {
atRuleType?: string;
atRuleParams?: string;
}): any;
/**
* Get all rules or filtered by a matching selector.
* @example
* // Take all the component specific rules
* const id = someComponent.getId();
* const rules = css.getRules(`#${id}`);
* console.log(rules.map(rule => rule.toCSS()))
* // All rules in the project
* console.log(css.getRules())
* @param [selector = ''] - Selector, eg. `.myclass`
*/
getRules(selector?: string): any;
/**
* Remove rule, by CssRule or matching selector (eg. the selector will match also at-rules like `@media`)
* @example
* // Remove by CssRule
* const toRemove = css.getRules('.my-cls');
* css.remove(toRemove);
* // Remove by selector
* css.remove('.my-cls-2');
*/
remove(): any;
/**
* Remove all rules
*/
clear(): this;
}
interface Styleable {
/**
* To trigger the style change event on models I have to
* pass a new object instance
* @param prop
*/
extendStyle(prop : object) : object
/**
* Get style object
*/
getStyle(prop? : string) : object
/**
* Set new style object
* @return {Object} Applied properties
*/
setStyle(prop : object | string = {}, opts = {}) : object
/**
* Add style property
* @example
* this.addStyle({color: 'red'});
* this.addStyle('color', 'blue');
*/
addStyle(prop : object | string, value = '', opts = {}) : void
/**
* Remove style property
*/
removeStyle(prop : string) : void
/**
* Returns string of style properties
*/
styleToString(opts = {}) : string
}
interface CssRuleOptions {
/**
* Array of selectors
*/
selectors: Selector[];
/**
* Object containing style definitions
*/
style: any;
/**
* Additional string css selectors
* @defaultValue ''
*/
selectorsAdd?: string;
/**
* Type of at-rule, eg. `media`, 'font-face'
* @defaultValue ''
*/
atRuleType?: string;
/**
* At-rule value, eg. `(max-width: 1000px)`
* @defaultValue ''
*/
mediaText?: string;
/**
* This property is used only on at-rules, like 'page' or 'font-face', where the block containes only style declarations
*/
singleAtRule?: boolean;
/**
* State of the rule, eg: `hover`, `focused`
* @defaultValue ''
*/
state?: string;
/**
* If true, sets `!important` on all properties. You can also pass an array to specify properties on which use important
*/
important?: boolean | String[];
/**
* Indicates if the rule is stylable from the editor
[Device]: device.html
[State]: state.html
[Component]: component.html
* @defaultValue true
*/
stylable?: boolean;
}
interface CssRule extends Backbone.Model<CssRuleOptions>, Styleable {
/**
* Returns the at-rule statement when exists, eg. `@media (...)`, `@keyframes`
* @example
* const cssRule = editor.Css.setRule('.class1', { color: 'red' }, {
* atRuleType: 'media',
* atRuleParams: '(min-width: 500px)'
* });
* cssRule.getAtRule(); // "@media (min-width: 500px)"
*/
getAtRule(): string;
/**
* Return selectors of the rule as a string
* @example
* const cssRule = editor.Css.setRule('.class1:hover', { color: 'red' });
* cssRule.selectorsToString(); // ".class1:hover"
* cssRule.selectorsToString({ skipState: true }); // ".class1"
* @param [opts] - Options
* @param [opts.skipState] - Skip state from the result
*/
selectorsToString(opts?: {
skipState?: boolean;
}): string;
/**
* Get declaration block (without the at-rule statement)
* @example
* const cssRule = editor.Css.setRule('.class1', { color: 'red' }, {
* atRuleType: 'media',
* atRuleParams: '(min-width: 500px)'
* });
* cssRule.getDeclaration() // ".class1{color:red;}"
* @param [opts = {}] - Options (same as in `selectorsToString`)
*/
getDeclaration(opts?: any): string;
/**
* Get the Device the rule is related to.
* @example
* const device = rule.getDevice();
* console.log(device?.getName());
*/
getDevice(): Device | null;
/**
* Get the State the rule is related to.
* @example
* const state = rule.getState();
* console.log(state?.getLabel());
*/
getState(): State | null;
/**
* Returns the related Component (valid only for component-specific rules).
* @example
* const cmp = rule.getComponent();
* console.log(cmp?.toHTML());
*/
getComponent(): Component | null;
/**
* Return the CSS string of the rule
* @example
* const cssRule = editor.Css.setRule('.class1', { color: 'red' }, {
* atRuleType: 'media',
* atRuleParams: '(min-width: 500px)'
* });
* cssRule.toCSS() // "@media (min-width: 500px){.class1{color:red;}}"
* @param [opts = {}] - Options (same as in `getDeclaration`)
* @returns CSS string
*/
toCSS(opts?: any): string;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/modal_dialog/config/config.js)
* ```js
* const editor = grapesjs.init({
* modal: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const modal = editor.Modal;
* ```
*
* ## Available Events
* * `modal:open` - Modal is opened
* * `modal:close` - Modal is closed
* * `modal` - Event triggered on any change related to the modal. An object containing all the available data about the triggered event is passed as an argument to the callback.
*
* ## Methods
* * [open](#open)
* * [close](#close)
* * [isOpen](#isopen)
* * [setTitle](#settitle)
* * [getTitle](#gettitle)
* * [setContent](#setcontent)
* * [getContent](#getcontent)
* * [onceClose](#onceclose)
* * [onceOpen](#onceopen)
*/
interface Modal {
/**
* Open the modal window
* @example
* modal.open({
* title: 'My title',
* content: 'My content',
* attributes: { class: 'my-class' },
* });
* @param [opts = {}] - Options
* @param [opts.title] - Title to set for the modal
* @param [opts.content] - Content to set for the modal
* @param [opts.attributes] - Updates the modal wrapper with custom attributes
*/
open(opts?: {
title?: string | HTMLElement;
content?: string | HTMLElement;
attributes?: any;
}): this;
/**
* Close the modal window
* @example
* modal.close();
*/
close(): this;
/**
* Execute callback when the modal will be closed.
* The callback will be called one only time
* @example
* modal.onceClose(() => {
* console.log('The modal is closed');
* });
* @param clb - Callback to call
*/
onceClose(clb: (...params: any[]) => any): this;
/**
* Execute callback when the modal will be opened.
* The callback will be called one only time
* @example
* modal.onceOpen(() => {
* console.log('The modal is opened');
* });
* @param clb - Callback to call
*/
onceOpen(clb: (...params: any[]) => any): this;
/**
* Checks if the modal window is open
* @example
* modal.isOpen(); // true | false
*/
isOpen(): boolean;
/**
* Set the title to the modal window
* @example
* // pass a string
* modal.setTitle('Some title');
* // or an HTMLElement
* const el = document.createElement('div');
* el.innerText = 'New title';
* modal.setTitle(el);
* @param title - Title
*/
setTitle(title: string | HTMLElement): this;
/**
* Returns the title of the modal window
* @example
* modal.getTitle();
*/
getTitle(): string | HTMLElement;
/**
* Set the content of the modal window
* @example
* // pass a string
* modal.setContent('Some content');
* // or an HTMLElement
* const el = document.createElement('div');
* el.innerText = 'New content';
* modal.setContent(el);
* @param content - Content
*/
setContent(content: string | HTMLElement): this;
/**
* Get the content of the modal window
* @example
* modal.getContent();
*/
getContent(): string | HTMLElement;
}
/**
* This module allows to customize the built-in toolbar of the Rich Text Editor and use commands from the [HTML Editing APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand).
* It's highly recommended to keep this toolbar as small as possible, especially from styling commands (eg. 'fontSize') and leave this task to the Style Manager
*
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/rich_text_editor/config/config.js)
* ```js
* const editor = grapesjs.init({
* richTextEditor: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('rte:enable', () => { ... });
*
* // Use the API
* const rte = editor.RichTextEditor;
* rte.add(...);
* ```
*
* ## Available Events
* * `rte:enable` - RTE enabled. The view, on which RTE is enabled, is passed as an argument
* * `rte:disable` - RTE disabled. The view, on which RTE is disabled, is passed as an argument
*
* ## Methods
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [remove](#remove)
* * [getToolbarEl](#gettoolbarel)
*/
interface RichTextEditor {
/**
* Add a new action to the built-in RTE toolbar
* @example
* rte.add('bold', {
* icon: '<b>B</b>',
* attributes: {title: 'Bold'},
* result: rte => rte.exec('bold')
* });
* rte.add('link', {
* icon: document.getElementById('t'),
* attributes: {title: 'Link',}
* // Example on it's easy to wrap a selected content
* result: rte => rte.insertHTML(`<a href="#">${rte.selection()}</a>`)
* });
* // An example with fontSize
* rte.add('fontSize', {
* icon: `<select class="gjs-field">
* <option>1</option>
* <option>4</option>
* <option>7</option>
* </select>`,
* // Bind the 'result' on 'change' listener
* event: 'change',
* result: (rte, action) => rte.exec('fontSize', action.btn.firstChild.value),
* // Callback on any input change (mousedown, keydown, etc..)
* update: (rte, action) => {
* const value = rte.doc.queryCommandValue(action.name);
* if (value != 'false') { // value is a string
* action.btn.firstChild.value = value;
* }
* }
* })
* // An example with state
* const isValidAnchor = (rte) => {
* // a utility function to help determine if the selected is a valid anchor node
* const anchor = rte.selection().anchorNode;
* const parentNode = anchor && anchor.parentNode;
* const nextSibling = anchor && anchor.nextSibling;
* return (parentNode && parentNode.nodeName == 'A') || (nextSibling && nextSibling.nodeName == 'A')
* }
* rte.add('toggleAnchor', {
* icon: `<span style="transform:rotate(45deg)">&supdsub;</span>`,
* state: (rte, doc) => {
* if (rte && rte.selection()) {
* // `btnState` is a integer, -1 for disabled, 0 for inactive, 1 for active
* return isValidAnchor(rte) ? btnState.ACTIVE : btnState.INACTIVE;
* } else {
* return btnState.INACTIVE;
* }
* },
* result: (rte, action) => {
* if (isValidAnchor(rte)) {
* rte.exec('unlink');
* } else {
* rte.insertHTML(`<a class="link" href="">${rte.selection()}</a>`);
* }
* }
* })
* @param name - Action name
* @param action - Action options
*/
add(name: string, action: any): void;
/**
* Get the action by its name
* @example
* const action = rte.get('bold');
* // {name: 'bold', ...}
* @param name - Action name
*/
get(name: string): any;
/**
* Get all actions
*/
getAll(): any[];
/**
* Remove the action from the toolbar
* @example
* const action = rte.remove('bold');
* // {name: 'bold', ...}
* @returns Removed action
*/
remove(name: string): any;
/**
* Get the toolbar element
*/
getToolbarEl(): HTMLElement;
}
/**
* You can customize the initial state of the module from the editor initialization
* ```js
* const editor = grapesjs.init({
* keymaps: {
* // Object of keymaps
* defaults: {
* 'your-namespace:keymap-name' {
* keys: '⌘+z, ctrl+z',
* handler: 'some-command-id'
* },
* ...
* }
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('keymap:add', () => { ... });
*
* // Use the API
* const keymaps = editor.Keymaps;
* keymaps.add(...);
* ```
*
* ## Available Events
* * `keymap:add` - New keymap added. The new keyamp object is passed as an argument
* * `keymap:remove` - Keymap removed. The removed keyamp object is passed as an argument
* * `keymap:emit` - Some keymap emitted, in arguments you get keymapId, shortcutUsed, Event
* * `keymap:emit:{keymapId}` - `keymapId` emitted, in arguments you get keymapId, shortcutUsed, Event
*
* ## Methods
* * [getConfig](#getconfig)
* * [add](#add)
* * [get](#get)
* * [getAll](#getAll)
* * [remove](#remove)
* * [removeAll](#removeall)
*/
interface Keymaps {
/**
* Get module configurations
* @returns Configuration object
*/
getConfig(): any;
/**
* Add new keymap
* @example
* // 'ns' is just a custom namespace
* keymaps.add('ns:my-keymap', '⌘+j, ⌘+u, ctrl+j, alt+u', editor => {
* console.log('do stuff');
* });
* // or
* keymaps.add('ns:my-keymap', '⌘+s, ctrl+s', 'some-gjs-command');
*
* // listen to events
* editor.on('keymap:emit', (id, shortcut, e) => {
* // ...
* })
* @param id - Keymap id
* @param keys - Keymap keys, eg. `ctrl+a`, `⌘+z, ctrl+z`
* @param handler - Keymap handler, might be a function
* @param [opts = {}] - Options
* @returns Added keymap
* or just a command id as a string
*/
add(id: string, keys: string, handler: ((...params: any[]) => any) | string, opts?: any): any;
/**
* Get the keymap by id
* @example
* keymaps.get('ns:my-keymap');
* // -> {keys, handler};
* @param id - Keymap id
* @returns Keymap object
*/
get(id: string): any;
/**
* Get all keymaps
* @example
* keymaps.getAll();
* // -> {id1: {}, id2: {}};
*/
getAll(): any;
/**
* Remove the keymap by id
* @example
* keymaps.remove('ns:my-keymap');
* // -> {keys, handler};
* @param id - Keymap id
* @returns Removed keymap
*/
remove(id: string): any;
/**
* Remove all binded keymaps
*/
removeAll(): Keymaps;
}
/**
* This module allows to manage the stack of changes applied in canvas.
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const um = editor.UndoManager;
* ```
*
* * [getConfig](#getconfig)
* * [add](#add)
* * [remove](#remove)
* * [removeAll](#removeall)
* * [start](#start)
* * [stop](#stop)
* * [undo](#undo)
* * [undoAll](#undoall)
* * [redo](#redo)
* * [redoAll](#redoall)
* * [hasUndo](#hasundo)
* * [hasRedo](#hasredo)
* * [getStack](#getstack)
* * [clear](#clear)
*/
interface UndoManager {
/**
* Get module configurations
* @example
* const config = um.getConfig();
* // { ... }
* @returns Configuration object
*/
getConfig(): any;
/**
* Add an entity (Model/Collection) to track
* Note: New Components and CSSRules will be added automatically
* @example
* um.add(someModelOrCollection);
* @param entity - Entity to track
*/
add(entity: Backbone.Model | Backbone.Collection<Backbone.Model>): UndoManager;
/**
* Remove and stop tracking the entity (Model/Collection)
* @example
* um.remove(someModelOrCollection);
* @param entity - Entity to remove
*/
remove(entity: Backbone.Model | Backbone.Collection<Backbone.Model>): UndoManager;
/**
* Remove all entities
* @example
* um.removeAll();
*/
removeAll(): UndoManager;
/**
* Start/resume tracking changes
* @example
* um.start();
*/
start(): UndoManager;
/**
* Stop tracking changes
* @example
* um.stop();
*/
stop(): UndoManager;
/**
* Undo last change
* @example
* um.undo();
*/
undo(): UndoManager;
/**
* Undo all changes
* @example
* um.undoAll();
*/
undoAll(): UndoManager;
/**
* Redo last change
* @example
* um.redo();
*/
redo(): UndoManager;
/**
* Redo all changes
* @example
* um.redoAll();
*/
redoAll(): UndoManager;
/**
* Checks if exists an available undo
* @example
* um.hasUndo();
*/
hasUndo(): boolean;
/**
* Checks if exists an available redo
* @example
* um.hasRedo();
*/
hasRedo(): boolean;
/**
* Check if the entity (Model/Collection) to tracked
* Note: New Components and CSSRules will be added automatically
* @param entity - Entity to track
*/
isRegistered(entity: Backbone.Model | Backbone.Collection<Backbone.Model>): boolean;
/**
* Get stack of changes
* @example
* const stack = um.getStack();
* stack.each(item => ...);
*/
getStack(): Backbone.Collection<Backbone.Model>;
/**
* Get grouped undo manager stack.
* The difference between `getStack` is when you do multiple operations at a time,
* like appending multiple components:
* `editor.getWrapper().append(`<div>C1</div><div>C2</div>`);`
* `getStack` will return a collection length of 2.
* `getStackGroup` instead will group them as a single operation (the first
* inserted component will be returned in the list) by returning an array length of 1.
*/
getStackGroup(): any[];
/**
* Clear the stack
* @example
* um.clear();
*/
clear(): UndoManager;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/canvas/config/config.js)
* ```js
* const editor = grapesjs.init({
* canvas: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
*
* ```js
* // Listen to events
* editor.on('canvas:drop', () => { ... });
*
* // Use the API
* const canvas = editor.Canvas;
* canvas.setCoords(...);
* ```
* ## Available Events
* * `canvas:dragenter` - When something is dragged inside the canvas, `DataTransfer` instance passed as an argument
* * `canvas:dragover` - When something is dragging on canvas, `DataTransfer` instance passed as an argument
* * `canvas:drop` - Something is dropped in canvas, `DataTransfer` instance and the dropped model are passed as arguments
* * `canvas:dragend` - When a drag operation is ended, `DataTransfer` instance passed as an argument
* * `canvas:dragdata` - On any dataTransfer parse, `DataTransfer` instance and the `result` are passed as arguments.
* By changing `result.content` you're able to customize what is dropped
*
* ## Methods
* * [getConfig](#getconfig)
* * [getElement](#getelement)
* * [getFrameEl](#getframeel)
* * [getWindow](#getwindow)
* * [getDocument](#getdocument)
* * [getBody](#getbody)
* * [setCustomBadgeLabel](#setcustombadgelabel)
* * [hasFocus](#hasfocus)
* * [scrollTo](#scrollto)
* * [setZoom](#setzoom)
* * [getZoom](#getzoom)
* * [getCoords](#getcoords)
* * [setCoords](#setcoords)
*
* [Component]: component.html
* [Frame]: frame.html
*/
interface Canvas {
/**
* Get the configuration object
* @example
* console.log(canvas.getConfig())
* @returns Configuration object
*/
getConfig(): CanvasConfig;
/**
* Get the canvas element
*/
getElement(): HTMLElement;
/**
* Get the main frame element of the canvas
*/
getFrameEl(): HTMLIFrameElement;
/**
* Get the main frame window instance
*/
getWindow(): Window;
/**
* Get the main frame document element
*/
getDocument(): HTMLDocument;
/**
* Get the main frame body element
*/
getBody(): HTMLBodyElement;
/**
* Set custom badge naming strategy
* @example
* canvas.setCustomBadgeLabel(function(component){
* return component.getName();
* });
*/
setCustomBadgeLabel(f: (...params: any[]) => any): void;
/**
* Get canvas rectangular data
*/
getRect(): any;
/**
* Check if the canvas is focused
*/
hasFocus(): boolean;
/**
* Scroll canvas to the element if it's not visible. The scrolling is
* executed via `scrollIntoView` API and options of this method are
* passed to it. For instance, you can scroll smoothly by using
* `{ behavior: 'smooth' }`.
* @example
* const selected = editor.getSelected();
* // Scroll smoothly (this behavior can be polyfilled)
* canvas.scrollTo(selected, { behavior: 'smooth' });
* // Force the scroll, even if the element is alredy visible
* canvas.scrollTo(selected, { force: true });
* @param [opts = {}] - Options, same as options for `scrollIntoView`
* @param [opts.force = false] - Force the scroll, even if the element is already visible
*/
scrollTo(el: HTMLElement | Component, opts?: {
force?: boolean;
}): void;
/**
* Set canvas zoom value
* @example
* canvas.setZoom(50); // set zoom to 50%
* @param value - The zoom value, from 0 to 100
*/
setZoom(value: number): this;
/**
* Get canvas zoom value
* @example
* canvas.setZoom(50); // set zoom to 50%
* const zoom = canvas.getZoom(); // 50
*/
getZoom(): number;
/**
* Set canvas position coordinates
* @example
* canvas.setCoords(100, 100);
* @param x - Horizontal position
* @param y - Vertical position
*/
setCoords(x: number, y: number): this;
/**
* Get canvas position coordinates
* @example
* canvas.setCoords(100, 100);
* const coords = canvas.getCoords();
* // { x: 100, y: 100 }
* @returns Object containing coordinates
*/
getCoords(): any;
/**
* Add new frame to the canvas
* @example
* canvas.addFrame({
* name: 'Mobile home page',
* x: 100, // Position in canvas
* y: 100,
* width: 500, // Frame dimensions
* height: 600,
* // device: 'DEVICE-ID',
* components: [
* '<h1 class="testh">Title frame</h1>',
* '<p class="testp">Paragraph frame</p>',
* ],
* styles: `
* .testh { color: red; }
* .testp { color: blue; }
* `,
* });
* @param props - Frame properties
*/
addFrame(props: any): any;
}
interface FrameOptions {
/**
* Wrapper component definition. You can also pass an HTML string as components of the default wrapper component.
*/
component: any | string;
/**
* Width of the frame. By default, the canvas width will be taken.
* @defaultValue ''
*/
width?: string;
/**
* Height of the frame. By default, the canvas height will be taken.
* @defaultValue ''
*/
height?: string;
/**
* Horizontal position of the frame in the canvas.
*/
x?: number;
/**
* Vertical position of the frame in the canvas.
*/
y?: number;
}
interface Frame extends Backbone.Model<FrameOptions> {
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/i18n/config.js)
* ```js
* const editor = grapesjs.init({
* i18n: {
* locale: 'en',
* localeFallback: 'en',
* messages: {
* it: { hello: 'Ciao', ... },
* ...
* }
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const i18n = editor.I18n;
* ```
*
* ### Events
* * `i18n:add` - New set of messages is added
* * `i18n:update` - The set of messages is updated
* * `i18n:locale` - Locale changed
*/
interface I18n {
/**
* Get module configurations
* @returns Configuration object
*/
getConfig(): any;
/**
* Update current locale
* @example
* i18n.setLocale('it');
* @param locale - Locale value
*/
setLocale(locale: string): this;
/**
* Get current locale
* @returns Current locale value
*/
getLocale(): string;
/**
* Get all messages
* @example
* i18n.getMessages();
* // -> { en: { hello: '...' }, ... }
* i18n.getMessages('en');
* // -> { hello: '...' }
* @param [lang] - Specify the language of messages to return
* @param [opts] - Options
* @param [opts.debug] - Show warnings in case of missing language
*/
getMessages(lang?: string, opts?: {
debug?: boolean;
}): any;
/**
* Set new set of messages
* @example
* i18n.getMessages();
* // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2', } }
* i18n.setMessages({ en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } });
* // Set replaced
* i18n.getMessages();
* // -> { en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } }
* @param msg - Set of messages
*/
setMessages(msg: any): this;
/**
* Update messages
* @example
* i18n.getMessages();
* // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2', } }
* i18n.addMessages({ en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } });
* // Set updated
* i18n.getMessages();
* // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2 up', msg3: 'Msg 3', } }
* @param msg - Set of messages to add
*/
addMessages(msg: any): this;
/**
* Translate the locale message
* @example
* obj.setMessages({
* en: { msg: 'Msg', msg2: 'Msg {test}'},
* it: { msg2: 'Msg {test} it'},
* });
* obj.t('msg');
* // -> outputs `Msg`
* obj.t('msg2', { params: { test: 'hello' } }); // use params
* // -> outputs `Msg hello`
* obj.t('msg2', { l: 'it', params: { test: 'hello' } }); // custom local
* // -> outputs `Msg hello it`
* @param key - Label to translate
* @param [opts] - Options for the translation
* @param [opts.params] - Params for the translation
* @param [opts.debug] - Show warnings in case of missing resources
*/
t(key: string, opts?: {
params?: any;
debug?: boolean;
}): string;
}
/**
* You can customize the initial state of the module from the editor initialization
* ```js
* const editor = grapesjs.init({
* ....
* pageManager: {
* pages: [
* {
* id: 'page-id',
* styles: `.my-class { color: red }`, // or a JSON of styles
* component: '<div class="my-class">My element</div>', // or a JSON of components
* }
* ]
* },
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const pageManager = editor.Pages;
* ```
*
* ## Available Events
* * `page:add` - Added new page. The page is passed as an argument to the callback
* * `page:remove` - Page removed. The page is passed as an argument to the callback
* * `page:select` - New page selected. The newly selected page and the previous one, are passed as arguments to the callback
* * `page:update` - Page updated. The updated page and the object containing changes are passed as arguments to the callback
* * `page` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback
*
* ## Methods
* * [add](#add)
* * [get](#get)
* * [getAll](#getall)
* * [getAllWrappers](#getallwrappers)
* * [getMain](#getmain)
* * [remove](#remove)
* * [select](#select)
* * [getSelected](#getselected)
*
* [Page]: page.html
* [Component]: component.html
*/
interface Pages {
/**
* Add new page
* @example
* const newPage = pageManager.add({
* id: 'new-page-id', // without an explicit ID, a random one will be created
* styles: `.my-class { color: red }`, // or a JSON of styles
* component: '<div class="my-class">My element</div>', // or a JSON of components
* });
* @param props - Page properties
* @param [opts] - Options
*/
add(props: any, opts?: any): any;
/**
* Remove page
* @example
* const removedPage = pageManager.remove('page-id');
* // or by passing the page
* const somePage = pageManager.get('page-id');
* pageManager.remove(somePage);
*/
remove(): any;
/**
* Get page by id
* @example
* const somePage = pageManager.get('page-id');
* @param id - Page id
*/
get(id: string): any;
/**
* Get main page (the first one available)
* @example
* const mainPage = pageManager.getMain();
*/
getMain(): any;
/**
* Get all pages
* @example
* const arrayOfPages = pageManager.getAll();
*/
getAll(): any;
/**
* Get wrapper components (aka body) from all pages and frames.
* @example
* const wrappers = pageManager.getAllWrappers();
* // Get all `image` components from the project
* const allImages = wrappers.map(wrp => wrp.findType('image')).flat();
*/
getAllWrappers(): any;
/**
* Change the selected page. This will switch the page rendered in canvas
* @example
* pageManager.select('page-id');
* // or by passing the page
* const somePage = pageManager.get('page-id');
* pageManager.select(somePage);
*/
select(): this;
/**
* Get the selected page
* @example
* const selectedPage = pageManager.getSelected();
*/
getSelected(): any;
}
interface PageOptions {
frames : Frame[]
}
interface Page extends Backbone.Model<PageOptions> {
/**
* Get page id
*/
getId(): string;
/**
* Get page name
*/
getName(): string;
/**
* Update page name
* @param value - New page name
*/
setName(value: string): void;
/**
* Get all frames
* @example
* const arrayOfFrames = page.getAllFrames();
*/
getAllFrames(): Frame[];
/**
* Get the first frame of the page (identified always as the main one)
* @example
* const mainFrame = page.getMainFrame();
*/
getMainFrame(): Frame;
/**
* Get the root component (usually is the `wrapper` component) from the main frame
* @example
* const rootComponent = page.getMainComponent();
* console.log(rootComponent.toHTML());
*/
getMainComponent(): Component;
}
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/parser/config/config.js)
* ```js
* const editor = grapesjs.init({
* parser: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const { Parser } = editor;
* ```
* ## Available Events
* * `parse:html` - On HTML parse, an object containing the input and the output of the parser is passed as an argument
* * `parse:css` - On CSS parse, an object containing the input and the output of the parser is passed as an argument
*
* ## Methods
* * [getConfig](#getconfig)
* * [parseHtml](#parsehtml)
* * [parseCss](#parsecss)
*/
interface Parser {
/**
* Get the configuration object
* @example
* console.log(Parser.getConfig())
* @returns Configuration object
*/
getConfig(): any;
/**
* Parse HTML string and return the object containing the Component Definition
* @example
* const resHtml = Parser.parseHtml(`<table><div>Hi</div></table>`, {
* htmlType: 'text/html', // default
* });
* // By using the `text/html`, this will fix automatically all the HTML syntax issues
* // Indeed the final representation, in this case, will be `<div>Hi</div><table></table>`
* const resXml = Parser.parseHtml(`<table><div>Hi</div></table>`, {
* htmlType: 'application/xml',
* });
* // This will preserve the original format as, from the XML point of view, is a valid format
* @param input - HTML string to parse
* @param [options] - Options
* @param [options.htmlType] - [HTML mime type](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02) to parse
* @param [options.allowScripts = false] - Allow `<script>` tags
* @param [options.allowUnsafeAttr = false] - Allow unsafe HTML attributes (eg. `on*` inline event handlers)
* @returns Object containing the result `{ html: ..., css: ... }`
*/
parseHtml(input: string, options?: {
htmlType?: string;
allowScripts?: boolean;
allowUnsafeAttr?: boolean;
}): any;
/**
* Parse CSS string and return an array of valid definition objects for CSSRules
* @example
* const res = Parser.parseCss('.cls { color: red }');
* // [{ ... }]
* @param input - CSS string to parse
* @returns Array containing the result
*/
parseCss(input: string): object[];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment