From fdf7b12af1cf72b5c2a497d9ab05ec656bce928f Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Wed, 24 Jan 2024 00:08:35 +0400 Subject: [PATCH] Fix TS bundle --- dist/index.d.ts | 3852 +++++++++++++++-------------- src/trait_manager/index.ts | 4 +- src/trait_manager/model/Traits.ts | 3 +- 3 files changed, 2001 insertions(+), 1858 deletions(-) diff --git a/dist/index.d.ts b/dist/index.d.ts index 435a43ea8..3cba58821 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -14,6 +14,9 @@ export type AddOptions = Backbone.AddOptions & { export type DisableOptions = { fromMove?: boolean; }; +export type LocaleOptions = { + locale?: boolean; +}; export type RemoveOptions = Backbone.Silenceable; export type EventHandler = Backbone.EventHandler; export type ObjectHash = Backbone.ObjectHash; @@ -1696,12 +1699,12 @@ declare class ComponentsView extends View { export type ClbObj = ReturnType; export interface IComponentView extends ExtractMethods { } -export declare class ComponentView extends View extends View { +TComp> { /** @ts-ignore */ - model: Component; + model: TComp; /** @ts-ignore */ className(): any; /** @ts-ignore */ @@ -1726,7 +1729,7 @@ Component> { __isDraggable(): string | boolean | DraggableDroppableFn | undefined; _clbObj(): { editor: Editor; - model: Component; + model: TComp; el: HTMLElement; }; /** @@ -1935,7 +1938,7 @@ export declare class CanvasSpot ext defaults(): T; get type(): "" | T["type"]; get component(): Component | undefined; - get componentView(): ComponentView | undefined; + get componentView(): ComponentView | undefined; get el(): HTMLElement | undefined; /** * Get the box rect of the spot. @@ -2678,172 +2681,92 @@ declare class TraitView extends View { postUpdate(): void; render(): this; } -/** @private */ -export interface TraitProperties { +export interface CategoryViewConfig { + em: EditorModel; + pStylePrefix?: string; + stylePrefix?: string; +} +declare class CategoryView extends View { + em: EditorModel; + config: CategoryViewConfig; + pfx: string; + caretR: string; + caretD: string; + iconClass: string; + activeClass: string; + iconEl?: HTMLElement; + typeEl?: HTMLElement; + catName: string; + events(): { + "click [data-title]": string; + }; + template({ pfx, label, catName }: { + pfx: string; + label: string; + catName: string; + }): string; + /** @ts-ignore */ + attributes(): Record; + constructor(o: any, config: CategoryViewConfig, catName: string); + updateVisibility(): void; + open(): void; + close(): void; + toggle(): void; + getIconEl(): HTMLElement; + getTypeEl(): HTMLElement; + append(el: HTMLElement): void; + render(): this; +} +interface CategoryProperties { /** - * Trait type, defines how the trait should rendered. - * Possible values: `text` (default), `number`, `select`, `checkbox`, `color`, `button` + * Category id. */ - type?: string; + id: string; /** - * The name of the trait used as a key for the attribute/property. - * By default, the name is used as attribute name or property in case `changeProp` in enabled. + * Category label. */ - name: string; + label: string; /** - * Trait id, eg. `my-trait-id`. - * If not specified, the `name` will be used as id. + * Category open state. + * @default true */ - id?: string; + open?: boolean; /** - * The trait label to show for the rendered trait. + * Category order. */ - label?: string | false; + order?: string | number; /** - * If `true` the trait value is applied on component + * Category attributes. + * @default {} */ - changeProp?: boolean; attributes?: Record; - valueTrue?: string; - valueFalse?: string; - min?: number; - max?: number; - unit?: string; - step?: number; - value?: any; - target?: Component; - default?: any; - placeholder?: string; - command?: string | ((editor: Editor, trait: Trait) => any); - options?: Record[]; - labelButton?: string; - text?: string; - full?: boolean; - getValue?: (props: { - editor: Editor; - trait: Trait; - component: Component; - }) => any; - setValue?: (props: { - value: any; - editor: Editor; - trait: Trait; - component: Component; - partial: boolean; - options: TraitSetValueOptions; - emitUpdate: () => void; - }) => void; } -export interface TraitSetValueOptions { - partial?: boolean; - [key: string]: unknown; +export interface ItemsByCategory { + category?: Category; + items: T[]; } -export type TraitOption = { - id: string; - label?: string; -}; -/** - * @typedef Trait - * @property {String} id Trait id, eg. `my-trait-id`. - * @property {String} type Trait type, defines how the trait should rendered. Possible values: `text` (default), `number`, `select`, `checkbox`, `color`, `button` - * @property {String} label The trait label to show for the rendered trait. - * @property {String} name The name of the trait used as a key for the attribute/property. By default, the name is used as attribute name or property in case `changeProp` in enabled. - * @property {Boolean} changeProp If `true` the trait value is applied on component - * - */ -export declare class Trait extends Model { - target: Component; - em: EditorModel; - view?: TraitView; - el?: HTMLElement; +export declare class Category extends Model { + view?: CategoryView; defaults(): { - type: string; + id: string; label: string; - name: string; - unit: string; - step: number; - value: string; - default: string; - placeholder: string; - changeProp: boolean; - options: never[]; + open: boolean; + attributes: {}; }; - constructor(prop: TraitProperties, em: EditorModel); - setTarget(target: Component): void; - /** - * Get the trait id. - * @returns {String} - */ getId(): string; - /** - * Get the trait type. - * @returns {String} - */ - getType(): string; - /** - * Get the trait name. - * @returns {String} - */ - getName(): string; - /** - * Get the trait label. - * @param {Object} [opts={}] Options. - * @param {Boolean} [opts.locale=true] Use the locale string from i18n module. - * @returns {String} - */ - getLabel(opts?: { - locale?: boolean; - }): any; - /** - * Get the trait value. - * The value is taken from component attributes by default or from properties if the trait has the `changeProp` enabled. - * @returns {any} - */ - getValue(): any; - /** - * Update the trait value. - * The value is applied on component attributes by default or on properties if the trait has the `changeProp` enabled. - * @param {any} value Value of the trait. - * @param {Object} [opts={}] Options. - * @param {Boolean} [opts.partial] If `true` the update won't be considered complete (not stored in UndoManager). - */ - setValue(value: any, opts?: TraitSetValueOptions): void; - /** - * Get default value. - */ - getDefault(): any; - /** - * Get trait options. - */ - getOptions(): TraitOption[]; - /** - * Get current selected option or by id. - * @param {String} [id] Option id. - * @returns {Object | null} - */ - getOption(id?: string): TraitOption | undefined; - /** - * Get the option id from the option object. - * @param {Object} option Option object - * @returns {String} Option id - */ - getOptionId(option: TraitOption): any; - /** - * Get option label. - * @param {String|Object} id Option id or the option object - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.locale=true] Use the locale string from i18n module - * @returns {String} Option label - */ - getOptionLabel(id: string | TraitOption, opts?: { - locale?: boolean; - }): string; - props(): Partial; - targetUpdated(): void; - getTargetValue(): any; - setTargetValue(value: any, opts?: SetOptions): void; - setValueFromInput(value: any, final?: boolean, opts?: SetOptions): void; - getInitValue(): any; + getLabel(): string; +} +export declare class Categories extends Collection { + /** @ts-ignore */ + add(model: (CategoryProperties | Category)[] | CategoryProperties | Category, opts?: AddOptions): Category; + get(id: string | Category): Category; +} +export interface ModelWithCategoryProps { + category?: string | CategoryProperties; +} +declare abstract class CollectionWithCategories> extends Collection { + abstract getCategories(): Categories; + initCategory(model: T): Category | undefined; } export interface TraitManagerConfig { /** @@ -2873,154 +2796,535 @@ declare class TraitFactory { build(prop: string | TraitProperties, em: EditorModel): Trait; private buildFromString; } -export declare class Traits extends Collection { +export interface TraitViewTypes { + [id: string]: { + new (o: any): TraitView; + }; +} +export interface ITraitView { + noLabel?: TraitView["noLabel"]; + eventCapture?: TraitView["eventCapture"]; + templateInput?: TraitView["templateInput"]; + onEvent?: TraitView["onEvent"]; + onUpdate?: TraitView["onUpdate"]; + createInput?: TraitView["createInput"]; + createLabel?: TraitView["createLabel"]; +} +export type CustomTrait = ITraitView & T & ThisType; +export interface TraitModuleStateProps { + component?: Component; + traits: Trait[]; +} +export interface TraitsByCategory extends ItemsByCategory { +} +export interface TraitManagerConfigModule extends TraitManagerConfig { + pStylePrefix?: string; em: EditorModel; - target: Component; - tf: TraitFactory; - constructor(coll: TraitProperties[], options: { - em: EditorModel; - }); - handleReset(coll: TraitProperties[], { previousModels }?: { - previousModels?: Trait[]; - }): void; - handleAdd(model: Trait): void; - setTarget(target: Component): void; - add(model: string | TraitProperties | Trait, options?: AddOptions): Trait; - add(models: Array, options?: AddOptions): Trait[]; } -export type RectDim = { - t: number; - l: number; - w: number; - h: number; -}; -export type BoundingRect = { - left: number; - top: number; - width: number; - height: number; -}; -export type CallbackOptions = { - docs: any; - config: any; - el: HTMLElement; - resizer: Resizer; -}; -export interface ResizerOptions { +export interface TraitCustomData { + container?: HTMLElement; +} +declare enum TraitsEvents { /** - * Function which returns custom X and Y coordinates of the mouse. + * @event `trait:custom` + * @example + * editor.on('trait:custom', () => { ... }); */ - mousePosFetcher?: (ev: Event) => Position; + custom = "trait:custom", /** - * Indicates custom target updating strategy. + * @event `trait` 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. + * @example + * editor.on('trait', ({ event, model, ... }) => { ... }); */ - updateTarget?: (el: HTMLElement, rect: RectDim, opts: any) => void; + all = "trait" +} +declare class DomainViews extends View { + config?: any; + items: any[]; + ns?: string; + itemView?: any; + itemsView: any; + itemType: string; + reuseView: boolean; + constructor(opts?: any, config?: any, autoAdd?: boolean); /** - * Function which gets HTMLElement as an arg and returns it relative position - */ - posFetcher?: (el: HTMLElement, opts: any) => BoundingRect; + * Add new model to the collection + * @param {Model} model + * @private + * */ + addTo(model: any): void; + itemViewNotFound(type: string): void; /** - * Indicate if the resizer should keep the default ratio. - * @default false - */ - ratioDefault?: boolean; + * Render new model inside the view + * @param {Model} model + * @param {Object} fragment Fragment collection + * @private + * */ + add(model: any, fragment?: DocumentFragment): void; + render(): this; + onRender(): void; + onRemoveBefore(items?: any, opts?: any): void; + onRemove(items?: any, opts?: any): void; + remove(opts?: {}): this; + clearItems(): void; +} +export interface TraitsViewProps { + el?: HTMLElement; + collection: any[]; + editor: EditorModel; + config: TraitManagerConfigModule; +} +declare class TraitsView extends DomainViews { + reuseView: boolean; + em: EditorModel; + pfx: string; + ppfx: string; + renderedCategories: Map; + config: TraitManagerConfigModule; + traitContClass: string; + catsClass: string; + catsEl?: HTMLElement; + traitsEl?: HTMLElement; + rendered?: boolean; + itemsView: TraitManager["types"]; + collection: Traits; + constructor(props: TraitsViewProps, itemsView: TraitManager["types"]); /** - * On resize start callback. + * Update view collection + * @private */ - onStart?: (ev: Event, opts: CallbackOptions) => void; + updatedCollection(): void; /** - * On resize move callback. - */ - onMove?: (ev: Event) => void; + * Render new model inside the view + * @param {Model} model + * @param {Object} fragment Fragment collection + * @private + * */ + add(model: Trait, fragment?: DocumentFragment): void; + getCategoriesEl(): HTMLElement; + getTraitsEl(): HTMLElement; + append(el: HTMLElement | DocumentFragment): void; + render(): this; +} +declare class TraitManager extends Module { + __ctn?: HTMLElement; + view?: TraitsView; + TraitsView: typeof TraitsView; + events: typeof TraitsEvents; + state: Model; + types: TraitViewTypes; /** - * On resize end callback. + * Get configuration object + * @name getConfig + * @function + * @return {Object} */ - onEnd?: (ev: Event, opts: CallbackOptions) => void; /** - * On container update callback. + * Initialize module + * @private */ - onUpdateContainer?: (opts: any) => void; + constructor(em: EditorModel); /** - * Resize unit step. - * @default 1 + * Select traits from component. + * @param {[Component]} component + * @example + * traitManager.select(someComponent); */ - step?: number; + select(component?: Component): void; /** - * Minimum dimension. - * @default 10 + * Get traits from the currently selected component. + * @return {Array} */ - minDim?: number; + getTraits(): Trait[]; /** - * Maximum dimension. - * @default Infinity + * Get traits by category from the currently selected component. + * @example + * traitManager.getTraitsByCategory(); + * // Returns an array of items of this type + * // > { category?: Category; items: Trait[] } + * + * // NOTE: The item without category is the one containing traits without category. */ - maxDim?: number; + getTraitsByCategory(): TraitsByCategory[]; /** - * Unit used for height resizing. - * @default 'px' + * + * Get Traits viewer + * @private */ - unitHeight?: string; + getTraitsViewer(): TraitsView | undefined; /** - * Unit used for width resizing. - * @default 'px' + * Add new trait type + * @param {string} name Type name + * @param {Object} methods Object representing the trait */ - unitWidth?: string; + addType(name: string, trait: CustomTrait): void; /** - * The key used for height resizing. - * @default 'height' + * Get trait type + * @param {string} name Type name + * @return {Object} */ - keyHeight?: string; + getType(name: string): new (o: any) => TraitView; /** - * The key used for width resizing. - * @default 'width' + * Get all trait types + * @returns {Object} */ - keyWidth?: string; + getTypes(): TraitViewTypes; /** - * If true, will override unitHeight and unitWidth, on start, with units - * from the current focused element (currently used only in SelectComponent). - * @default true + * Get trait categories from the currently selected component. + * @return {Array} */ - currentUnit?: boolean; + getCategories(): Category[]; + getCurrent(): Trait[]; + render(): HTMLElement; + postRender(): void; + __trgCustom(opts?: TraitCustomData): void; + __customData(): TraitCustomData; + __upSel(): void; + __onUp(): void; +} +export declare class Traits extends CollectionWithCategories { + em: EditorModel; + target: Component; + tf: TraitFactory; + categories: Categories; + constructor(coll: TraitProperties[], options: { + em: EditorModel; + }); + get module(): TraitManager; + getCategories(): Categories; + handleReset(coll: TraitProperties[], { previousModels }?: { + previousModels?: Trait[]; + }): void; + handleAdd(model: Trait): void; + setTarget(target: Component): void; + add(model: string | TraitProperties | Trait, options?: AddOptions): Trait; + add(models: Array, options?: AddOptions): Trait[]; +} +/** @private */ +export interface TraitProperties { /** - * With this option enabled the mousemove event won't be altered when the pointer comes over iframes. - * @default false + * Trait type, defines how the trait should rendered. + * Possible values: `text` (default), `number`, `select`, `checkbox`, `color`, `button` */ - silentFrames?: boolean; + type?: string; /** - * If true the container of handlers won't be updated. - * @default false + * The name of the trait used as a key for the attribute/property. + * By default, the name is used as attribute name or property in case `changeProp` in enabled. */ - avoidContainerUpdate?: boolean; + name?: string; /** - * If height is 'auto', this setting will preserve it and only update the width. - * @default false + * Trait id, eg. `my-trait-id`. + * If not specified, the `name` will be used as id. */ - keepAutoHeight?: boolean; + id?: string | number; /** - * If width is 'auto', this setting will preserve it and only update the height. - * @default false + * Trait category. + * @default '' */ - keepAutoWidth?: boolean; + category?: string | CategoryProperties; /** - * When keepAutoHeight is true and the height has the value 'auto', this is set to true and height isn't updated. - * @default false + * The trait label to show for the rendered trait. */ - autoHeight?: boolean; + label?: string | false; /** - * When keepAutoWidth is true and the width has the value 'auto', this is set to true and width isn't updated. - * @default false + * If `true` the trait value is applied on component */ - autoWidth?: boolean; + changeProp?: boolean; + attributes?: Record; + valueTrue?: string; + valueFalse?: string; + min?: number; + max?: number; + unit?: string; + step?: number; + value?: any; + target?: Component; + default?: any; + placeholder?: string; + command?: string | ((editor: Editor, trait: Trait) => any); + options?: Record[]; + labelButton?: string; + text?: string; + full?: boolean; + getValue?: (props: { + editor: Editor; + trait: Trait; + component: Component; + }) => any; + setValue?: (props: { + value: any; + editor: Editor; + trait: Trait; + component: Component; + partial: boolean; + options: TraitSetValueOptions; + emitUpdate: () => void; + }) => void; +} +export interface TraitSetValueOptions { + partial?: boolean; + [key: string]: unknown; +} +export type TraitOption = { + id: string; + label?: string; +}; +/** + * @typedef Trait + * @property {String} id Trait id, eg. `my-trait-id`. + * @property {String} type Trait type, defines how the trait should rendered. Possible values: `text` (default), `number`, `select`, `checkbox`, `color`, `button` + * @property {String} label The trait label to show for the rendered trait. + * @property {String} name The name of the trait used as a key for the attribute/property. By default, the name is used as attribute name or property in case `changeProp` in enabled. + * @property {String} [category=''] Trait category. + * @property {Boolean} changeProp If `true` the trait value is applied on component + * + */ +export declare class Trait extends Model { + target: Component; + em: EditorModel; + view?: TraitView; + el?: HTMLElement; + defaults(): { + type: string; + label: string; + name: string; + unit: string; + step: number; + value: string; + default: string; + placeholder: string; + category: string; + changeProp: boolean; + options: never[]; + }; + constructor(prop: TraitProperties, em: EditorModel); + get parent(): Traits; + get category(): Category | undefined; + setTarget(target: Component): void; /** - * Enable top left handler. - * @default true + * Get the trait id. + * @returns {String} */ - tl?: boolean; + getId(): string | number; /** - * Enable top center handler. - * @default true + * Get the trait type. + * @returns {String} */ - tc?: boolean; + getType(): string; + /** + * Get the trait name. + * @returns {String} + */ + getName(): string; + /** + * Get the trait label. + * @param {Object} [opts={}] Options. + * @param {Boolean} [opts.locale=true] Use the locale string from i18n module. + * @returns {String} + */ + getLabel(opts?: { + locale?: boolean; + }): any; + /** + * Get the trait value. + * The value is taken from component attributes by default or from properties if the trait has the `changeProp` enabled. + * @returns {any} + */ + getValue(): any; + /** + * Update the trait value. + * The value is applied on component attributes by default or on properties if the trait has the `changeProp` enabled. + * @param {any} value Value of the trait. + * @param {Object} [opts={}] Options. + * @param {Boolean} [opts.partial] If `true` the update won't be considered complete (not stored in UndoManager). + */ + setValue(value: any, opts?: TraitSetValueOptions): void; + /** + * Get default value. + */ + getDefault(): any; + /** + * Get trait options. + */ + getOptions(): TraitOption[]; + /** + * Get current selected option or by id. + * @param {String} [id] Option id. + * @returns {Object | null} + */ + getOption(id?: string): TraitOption | undefined; + /** + * Get the option id from the option object. + * @param {Object} option Option object + * @returns {String} Option id + */ + getOptionId(option: TraitOption): any; + /** + * Get option label. + * @param {String|Object} id Option id or the option object + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.locale=true] Use the locale string from i18n module + * @returns {String} Option label + */ + getOptionLabel(id: string | TraitOption, opts?: LocaleOptions): string; + /** + * Get category label. + * @param {Object} [opts={}] Options. + * @param {Boolean} [opts.locale=true] Use the locale string from i18n module. + * @returns {String} + */ + getCategoryLabel(opts?: LocaleOptions): string; + props(): Partial; + targetUpdated(): void; + getTargetValue(): any; + setTargetValue(value: any, opts?: SetOptions): void; + setValueFromInput(value: any, final?: boolean, opts?: SetOptions): void; + getInitValue(): any; +} +export type RectDim = { + t: number; + l: number; + w: number; + h: number; +}; +export type BoundingRect = { + left: number; + top: number; + width: number; + height: number; +}; +export type CallbackOptions = { + docs: any; + config: any; + el: HTMLElement; + resizer: Resizer; +}; +export interface ResizerUpdateTargetOptions { + store: boolean; + selectedHandler?: string; + resizer: Resizer; + config: ResizerOptions; +} +export interface ResizerOnUpdateContainerOptions { + el: HTMLElement; + resizer: Resizer; + opts: ResizerOptions; +} +export interface ResizerOptions { + /** + * Function which returns custom X and Y coordinates of the mouse. + */ + mousePosFetcher?: (ev: Event) => Position; + /** + * Indicates custom target updating strategy. + */ + updateTarget?: (el: HTMLElement, rect: RectDim, opts: ResizerUpdateTargetOptions) => void; + /** + * Function which gets HTMLElement as an arg and returns it relative position + */ + posFetcher?: (el: HTMLElement, opts: ElementPosOpts) => BoundingRect; + /** + * Indicate if the resizer should keep the default ratio. + * @default false + */ + ratioDefault?: boolean; + /** + * On resize start callback. + */ + onStart?: (ev: Event, opts: CallbackOptions) => void; + /** + * On resize move callback. + */ + onMove?: (ev: Event) => void; + /** + * On resize end callback. + */ + onEnd?: (ev: Event, opts: CallbackOptions) => void; + /** + * On container update callback. + */ + onUpdateContainer?: (opts: ResizerOnUpdateContainerOptions) => void; + /** + * Resize unit step. + * @default 1 + */ + step?: number; + /** + * Minimum dimension. + * @default 10 + */ + minDim?: number; + /** + * Maximum dimension. + * @default Infinity + */ + maxDim?: number; + /** + * Unit used for height resizing. + * @default 'px' + */ + unitHeight?: string; + /** + * Unit used for width resizing. + * @default 'px' + */ + unitWidth?: string; + /** + * The key used for height resizing. + * @default 'height' + */ + keyHeight?: string; + /** + * The key used for width resizing. + * @default 'width' + */ + keyWidth?: string; + /** + * If true, will override unitHeight and unitWidth, on start, with units + * from the current focused element (currently used only in SelectComponent). + * @default true + */ + currentUnit?: boolean; + /** + * With this option enabled the mousemove event won't be altered when the pointer comes over iframes. + * @default false + */ + silentFrames?: boolean; + /** + * If true the container of handlers won't be updated. + * @default false + */ + avoidContainerUpdate?: boolean; + /** + * If height is 'auto', this setting will preserve it and only update the width. + * @default false + */ + keepAutoHeight?: boolean; + /** + * If width is 'auto', this setting will preserve it and only update the height. + * @default false + */ + keepAutoWidth?: boolean; + /** + * When keepAutoHeight is true and the height has the value 'auto', this is set to true and height isn't updated. + * @default false + */ + autoHeight?: boolean; + /** + * When keepAutoWidth is true and the width has the value 'auto', this is set to true and width isn't updated. + * @default false + */ + autoWidth?: boolean; + /** + * Enable top left handler. + * @default true + */ + tl?: boolean; + /** + * Enable top center handler. + * @default true + */ + tc?: boolean; /** * Enable top right handler. * @default true @@ -3300,7 +3604,7 @@ export type DraggableDroppableFn = (source: Component, target: Component, index? export interface ComponentStackItem { id: string; model: typeof Component; - view: typeof ComponentView; + view: typeof ComponentView; } /** * Delegate commands to other components. @@ -4425,8 +4729,8 @@ export declare class Component extends StyleableModel { * @param {Frame} frame Get View of a specific frame * @return {ComponentView} */ - getView(frame?: Frame): ComponentView | undefined; - getCurrentView(): ComponentView | undefined; + getView(frame?: Frame): ComponentView | undefined; + getCurrentView(): ComponentView | undefined; __getScriptProps(): Partial; /** * Return script in string format, cleans 'function() {..' from scripts @@ -4680,92 +4984,34 @@ export interface AssetManagerConfig { */ dropzoneContent?: string; } -export interface CategoryViewConfig { - em: EditorModel; - pStylePrefix?: string; -} -declare class CategoryView extends View { +export declare class Blocks extends CollectionWithCategories { em: EditorModel; - config: CategoryViewConfig; - pfx: string; - caretR: string; - caretD: string; - iconClass: string; - activeClass: string; - iconEl?: HTMLElement; - blocksEl?: HTMLElement; - events(): { - "click [data-title]": string; - }; - template({ pfx, label }: { - pfx: string; - label: string; - }): string; - /** @ts-ignore */ - attributes(): Record; - constructor(o: any, config: CategoryViewConfig); - updateVisibility(): void; - open(): void; - close(): void; - toggle(): void; - getIconEl(): HTMLElement; - getBlocksEl(): HTMLElement; - append(el: HTMLElement): void; - render(): this; + constructor(coll: any[], options: { + em: EditorModel; + }); + getCategories(): Categories; + handleAdd(model: Block): void; } -export interface BlockCategoryProperties { +/** @private */ +export interface BlockProperties { /** - * Category id. + * Block label, eg. `My block` */ - id: string; + label: string; /** - * Category label. + * The content of the block. Might be an HTML string or a [Component Defintion](/modules/Components.html#component-definition) */ - label: string; + content: string | ComponentDefinition; /** - * Category open state. - * @default true + * HTML string for the media/icon of the block, eg. `; -} -export declare class Category extends Model { - view?: CategoryView; - defaults(): { - id: string; - label: string; - open: boolean; - attributes: {}; - }; -} -/** @private */ -export interface BlockProperties { - /** - * 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 | ComponentDefinition; - /** - * HTML string for the media/icon of the block, eg. ` { onClick: undefined; attributes: {}; }; + get category(): Category | undefined; + get parent(): Blocks; /** * Get block id * @returns {String} @@ -5848,104 +6096,6 @@ export interface CommandsConfig { */ strict?: boolean; } -/** @private */ -export interface SectorProperties { - id?: string; - name: string; - open?: boolean; - visible?: boolean; - buildProps?: string[]; - extendBuilded?: boolean; - properties?: PropertyProps[]; -} -/** - * - * [Property]: property.html - * - * @typedef Sector - * @property {String} id Sector id, eg. `typography` - * @property {String} name Sector name, eg. `Typography` - * @property {Boolean} [open=true] Indicates the open state. - * @property {Array} [properties=[]] Indicate an array of Property defintions. - */ -export declare class Sector extends Model { - em: EditorModel; - defaults(): { - id: string; - name: string; - open: boolean; - visible: boolean; - extendBuilded: boolean; - properties: never[]; - }; - /** - * @hideconstructor - */ - constructor(prp: SectorProperties, opts?: { - em?: EditorModel; - }); - get properties(): Collection>; - /** - * Get sector id. - * @returns {String} - */ - getId(): string; - /** - * Get sector name. - * @returns {String} - */ - getName(): string; - /** - * Update sector name. - * @param {String} value New sector name - */ - setName(value: string): this; - /** - * Check if the sector is open - * @returns {Boolean} - */ - isOpen(): boolean; - /** - * Update Sector open state - * @param {Boolean} value - */ - setOpen(value: boolean): this; - /** - * Check if the sector is visible - * @returns {Boolean} - */ - isVisible(): boolean; - /** - * Get sector properties. - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.withValue=false] Get only properties with value - * @param {Boolean} [opts.withParentValue=false] Get only properties with parent value - * @returns {Array<[Property]>} - */ - getProperties(opts?: { - withValue?: boolean; - withParentValue?: boolean; - }): Property[]; - getProperty(id: string): Property | undefined; - addProperty(property: PropertyProps, opts: AddOptions): any; - /** - * Extend properties - * @param {Array} props Start properties - * @param {Array} moProps Model props - * @param {Boolean} ex Returns the same amount of passed model props - * @return {Array} Final props - * @private - */ - extendProperties(props: PropertyProps[], moProps?: PropertyProps[], ex?: boolean): PropertyProps[]; - checkExtend(prop: any): PropertyProps; - /** - * Build properties - * @param {Array} propr Array of props as sting - * @return {Array} - * @private - */ - buildProperties(props: string | string[]): PropertyProps[]; -} declare class Input extends View { ppfx: string; em: EditorModel; @@ -6235,7 +6385,7 @@ export interface PropertyCompositeProps extends PropertyProps { /** * Value used to split property values, default `" "`. */ - separator: string; + separator?: string; /** * Value used to join property values, default `" "`. */ @@ -6645,1663 +6795,1766 @@ export declare class Property = PropertyProps> ext sectors?: Sector[]; }): boolean; } -export interface StyleManagerConfig { +/** @private */ +export interface SectorProperties { + id?: string; + name: string; + open?: boolean; + visible?: boolean; + buildProps?: string[]; + extendBuilded?: boolean; + properties?: PropertyProps[]; +} +/** + * + * [Property]: property.html + * + * @typedef Sector + * @property {String} id Sector id, eg. `typography` + * @property {String} name Sector name, eg. `Typography` + * @property {Boolean} [open=true] Indicates the open state. + * @property {Array} [properties=[]] Indicate an array of Property defintions. + */ +export declare class Sector extends Model { + em: EditorModel; + defaults(): { + id: string; + name: string; + open: boolean; + visible: boolean; + extendBuilded: boolean; + properties: never[]; + }; /** - * Default sectors and properties + * @hideconstructor */ - sectors?: (Omit & { - properties?: (string | PropertyProps)[]; - })[]; + constructor(prp: SectorProperties, opts?: { + em?: EditorModel; + }); + get properties(): Collection>; /** - * Specify the element to use as a container, string (query) or HTMLElement. - * With the empty value, nothing will be rendered. + * Get sector id. + * @returns {String} */ - appendTo?: string | HTMLElement; + getId(): string; /** - * Style prefix. - * @default 'sm-' + * Get sector name. + * @returns {String} */ - stylePrefix?: string; + getName(): string; /** - * Avoid rendering the default style manager. - * @default false + * Update sector name. + * @param {String} value New sector name */ - custom?: boolean; + setName(value: string): this; /** - * Hide the property in case it's not stylable for the - * selected component (each component has 'stylable' property). - * @deprecated + * Check if the sector is open + * @returns {Boolean} */ - hideNotStylable?: boolean; + isOpen(): boolean; /** - * Highlight changed properties of the selected component. - * @deprecated + * Update Sector open state + * @param {Boolean} value */ - highlightChanged?: boolean; + setOpen(value: boolean): this; /** - * Highlight computed properties of the selected component. - * @deprecated + * Check if the sector is visible + * @returns {Boolean} */ - highlightComputed?: boolean; + isVisible(): boolean; /** - * Show computed properties of the selected component, if this value - * is set to false, highlightComputed will not take effect. - * @deprecated + * Get sector properties. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.withValue=false] Get only properties with value + * @param {Boolean} [opts.withParentValue=false] Get only properties with parent value + * @returns {Array<[Property]>} */ - showComputed?: boolean; + getProperties(opts?: { + withValue?: boolean; + withParentValue?: boolean; + }): Property[]; + getProperty(id: string): Property | undefined; + addProperty(property: PropertyProps, opts: AddOptions): any; /** - * Adds the possibility to clear property value from the target style. - * @deprecated + * Extend properties + * @param {Array} props Start properties + * @param {Array} moProps Model props + * @param {Boolean} ex Returns the same amount of passed model props + * @return {Array} Final props + * @private */ - clearProperties?: boolean; + extendProperties(props: PropertyProps[], moProps?: PropertyProps[], ex?: boolean): PropertyProps[]; + checkExtend(prop: any): PropertyProps; /** - * Properties not to take in account for computed styles. - * @deprecated + * Build properties + * @param {Array} propr Array of props as sting + * @return {Array} + * @private */ - avoidComputed?: string[]; - pStylePrefix?: string; + buildProperties(props: string | string[]): PropertyProps[]; } -export type HTMLGeneratorBuildOptions = { - /** - * Remove unnecessary IDs (eg. those created automatically). - */ - cleanId?: boolean; - /** - * 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. - */ - attributes?: Record | ((component: Component, attr: Record) => Record); -}; -export type CssGeneratorBuildOptions = { - /** - * Return an array of CssRules instead of the CSS string. - */ - json?: boolean; +export declare class Sectors extends Collection { + em: EditorModel; + module: any; + initialize(prop: any, opts?: { + em?: EditorModel; + module?: any; + }): void; + /** @ts-ignore */ + model(props: any, opts?: {}): Sector; + onReset(models: any, opts?: { + previousModels?: Sector[]; + }): void; +} +export declare const Properties: any; +export type Option = { + id: string; + label?: string; +}; +declare class PropertyFactory { + props: Record; + typeNumber: string; + typeColor: string; + typeRadio: string; + typeSelect: string; + typeFile: string; + typeSlider: string; + typeComposite: string; + typeStack: string; + unitsSize: string[]; + unitsSizeNoPerc: string[]; + unitsTime: string[]; + unitsAngle: string[]; + fixedValues: string[]; + optsBgSize: Option[]; + optsBgAttach: Option[]; + optsBgRepeat: Option[]; + optsWrap: Option[]; + optsOverflow: Option[]; + optsDir: Option[]; + opstDisplay: Option[]; + optsTransitFn: Option[]; + optsCursor: Option[]; + optsFloat: Option[]; + optsPos: Option[]; + optsTextAlign: Option[]; + optsFlexAlign: Option[]; + optsJustCont: Option[]; + optsAlignCont: Option[]; + optsAlignSelf: Option[]; + optsTransitProp: Option[]; + optsBorderStyle: Option[]; + optsBgPos: Option[]; + optsWeight: Option[]; + optsShadowType: Option[]; + optsFonts: Option[]; + fixedFontSizes: string[]; + fixedLetSpace: string[]; + requireFlex: Record; + constructor(); + __sub(items: (string | PropertyProps)[]): () => PropertyProps[]; + init(): this; + add(property: string, def?: Record, opts?: { + from?: string; + }): any; + get(prop: string): PropertyProps | undefined; /** - * Return only rules matched by the passed component. + * Build props object by their name + * @param {Array|string} props Array of properties name + * @return {Array} */ - onlyMatched?: boolean; + build(props: string | string[]): PropertyProps[]; +} +declare class SectorsView extends View { + pfx: string; + ppfx: string; + config: StyleManagerConfig; + module: any; + constructor(o?: { + module?: any; + config?: StyleManagerConfig; + el?: HTMLElement; + em?: EditorModel; + collection?: Sectors; + }); + remove(): this; + addTo(model: Sector, c: any, opts?: {}): void; + addToCollection(model: Sector, fragmentEl: DocumentFragment | null, opts?: { + at?: number; + }): HTMLElement; + render(): this; +} +export interface ICustomPropertyView { + create?: (data: ReturnType) => any; + destroy?: (data: ReturnType) => any; + update?: (data: ReturnType & { + value: string; + }) => any; + emit?: (data: ReturnType, ...args: any) => any; + unset?: (data: ReturnType) => any; +} +export type CustomPropertyView = ICustomPropertyView & T & ThisType; +declare class PropertyView extends View { + em: EditorModel; + pfx: string; + ppfx: string; + config: any; + parent?: PropertyView; + __destroyFn: Function; + create?: Function; + destroy?: Function; + update?: Function; + emit?: Function; + unset?: Function; + clearEl?: HTMLElement; + createdEl?: HTMLElement; + input?: HTMLInputElement; + $input?: any; + constructor(o?: {}); + events(): { + change: string; + "click [data-clear-style]": string; + }; + template(model: any): string; + templateLabel(model: Property): string; + templateInput(model: Property): string; + remove(): this; /** - * Force keep all defined rules. Toggle on in case output looks different inside/outside of the editor. + * Triggers when the status changes. The status indicates if the value of + * the proprerty is changed or inherited + * @private */ - keepUnusedStyles?: boolean; - rules?: CssRule[]; - clearStyles?: boolean; -}; -export interface EditorConfig { + updateStatus(): void; /** - * Style class name prefix. - * @default 'gjs-' + * Clear the property from the target */ - stylePrefix?: string; + clear(ev: Event): void; /** - * Selector which indicates where render the editor. + * Get clear element + * @return {HTMLElement} */ - container?: string | HTMLElement; + getClearEl(): HTMLElement; /** - * If true, auto-render the content - * @default true + * Triggers when the value of element input/s is changed, so have to update + * the value of the model which will propogate those changes to the target */ - autorender?: boolean; + inputValueChanged(ev: any): void; + onValueChange(m: any, val: any, opt?: any): void; /** - * Array of plugins to execute on start. - * @default [] - */ - plugins?: (string | Plugin)[]; + * Update the element input. + * Usually the value is a result of `model.getFullValue()` + * @param {String} value The value from the model + * */ + setValue(value: string): void; + __setValueInput(value: string): void; + getInputEl(): HTMLInputElement; + updateVisibility(): void; + clearCached(): void; + __unset(): void; + __update(value: string): void; + __change(...args: any): void; + __updateStyle(value: string | StyleProps, { complete, partial, ...opts }?: any): void; + _getClbOpts(): { + el: HTMLElement; + createdEl: HTMLElement | undefined; + property: Property; + props: Partial; + change: (...args: any) => void; + updateStyle: (value: string | StyleProps, { complete, partial, ...opts }?: any) => void; + }; + render(): this; + onRender(): void; +} +declare class PropertiesView extends View { + config?: any; + pfx: string; + properties: PropertyView[]; + parent?: PropertyView; + constructor(o: any); + addTo(model: any, coll: any, opts: any): void; + add(model: any, frag: DocumentFragment | null, opts?: any): void; + remove(): this; + clearItems(): void; + render(): this; +} +declare class PropertyCompositeView extends PropertyView { + props?: PropertiesView; + templateInput(): string; + remove(): this; + onValueChange(): void; + onRender(): void; + clearCached(): void; +} +declare class LayersView extends View { + pfx: string; + ppfx: string; + config: any; + propertyView: PropertyStackView; + items: LayerView[]; + sorter: any; + constructor(o: any); + addTo(model: Layer): void; + addToCollection(model: Layer, fragmentEl: DocumentFragment | null, index?: number): HTMLElement; + reset(coll: any, opts: any): void; + remove(): this; + clearItems(): void; + render(): this; +} +declare class PropertyStackView extends PropertyCompositeView { + model: PropertyStack; + layersView?: LayersView; + events(): { + "click [data-add-layer]": string; + change: string; + "click [data-clear-style]": string; + }; + templateInput(): string; + init(): void; + addLayer(): void; /** - * Custom options for plugins - * @default {} + * There is no need to handle input update by the property itself, + * this will be done by layers + * @private */ - pluginsOpts?: Record; + setValue(): void; + remove(): this; + clearCached(): void; + onRender(): void; +} +declare class LayerView extends View { + pfx: string; + ppfx: string; + em: EditorModel; + propertyView: PropertyStackView; + propsWrapEl?: HTMLElement; + previewEl?: HTMLElement; + labelEl?: HTMLElement; + sorter: any; + config: any; + events(): { + click: string; + "click [data-close-layer]": string; + "mousedown [data-move-layer]": string; + "touchstart [data-move-layer]": string; + }; + template(): string; + initialize(o?: any): void; + initSorter(): void; + removeItem(ev: Event): void; + select(): void; + getPropertiesWrapper(): HTMLElement; + getPreviewEl(): HTMLElement; + getLabelEl(): HTMLElement; + updateLabel(): void; + updateVisibility(): void; + render(): this; +} +export type LayerValues = Record; +export interface LayerProps { + values: LayerValues; +} +declare class Layer extends Model { + prop: any; + view?: LayerView; + defaults(): { + values: {}; + }; + initialize(): void; /** - * Init headless editor. - * @default false + * Get layer id. + * @returns {String} */ - headless?: boolean; + getId(): string; /** - * Initial project data (JSON containing your components/styles/etc) to load. + * Get layer index. + * @returns {Number} */ - projectData?: ObjectAny; + getIndex(): number; /** - * HTML string or object of components - * @deprecated Rely on `projectData` option - * @default '' + * Get layer values. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.camelCase] Return property names in camelCase. + * @returns {Object} */ - components?: string; + getValues(opts?: { + camelCase?: boolean; + }): LayerValues; /** - * CSS string or object of rules - * @deprecated Rely on `projectData` option - * @default '' + * Get layer label. + * @returns {String} */ - style?: string; + getLabel(): string; /** - * If true, will fetch HTML and CSS from the selected container. - * @deprecated - * @default false + * Check if the layer is selected. + * @returns {Boolean} */ - fromElement?: boolean; + isSelected(): boolean; /** - * Show an alert before unload the page with unsaved changes - * @default true + * Select the layer. */ - noticeOnUnload?: boolean; + select(): any; /** - * Show paddings and margins. - * @default false + * Remove the layer. */ - showOffsets?: boolean; + remove(): any; /** - * Show paddings and margins on selected component - * @default false + * Move layer to a new index. + * @param {Number} index New index */ - showOffsetsSelected?: boolean; + move(index: number): any; /** - * 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. - * @default true + * Get style object for the preview. + * @param {Object} [opts={}] Options. Same of `PropertyStack.getStyleFromLayer` + * @returns {Object} Style object */ - forceClass?: boolean; + getStylePreview(opts?: OptionStyleStack): Record; /** - * Height for the editor container - * @default '900px' + * Check if the property has the preview enabled for this layer. + * @returns {Boolean} */ - height?: string; + hasPreview(): boolean; + upValues(props?: LayerValues): this; +} +declare class Layers extends Collection { + prop: any; + initialize(p: any, opts?: { + prop?: any; + }): void; +} +export type ToStyleDataStack = Omit & { + joinLayers: string; + layer: Layer; + property: PropertyStack; +}; +export type FromStyleDataStack = Omit & { + property: PropertyStack; + separatorLayers: RegExp; +}; +export type OptionStyleStack = OptionsStyle & { + number?: { + min?: number; + max?: number; + }; +}; +/** @private */ +export interface PropertyStackProps extends Omit { + layers?: LayerProps[]; /** - * Width for the editor container - * @default '100%' + * The separator used to split layer values. */ - width?: string; + layerSeparator?: string | RegExp; /** - * 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. - * @default ['warning', 'error'] + * Value used to join layer values. */ - log?: ("debug" | "info" | "warning" | "error")[] | boolean; + layerJoin?: string; /** - * 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. - * @deprecated in favor of `config.canvas.frameStyle` - * @default '' + * Indicate if the layer should display a preview. */ - baseCss?: string; + preview?: boolean; /** - * CSS that could only be seen (for instance, inside the code viewer) - * @default '* { box-sizing: border-box; } body {margin: 0;}' + * Custom logic for creating layer labels. */ - protectedCss?: string; + layerLabel?: (layer: Layer, data: { + index: number; + values: LayerValues; + property: PropertyStack; + }) => string; + toStyle?: (values: PropValues, data: ToStyleDataStack) => ReturnType; + fromStyle?: (style: StyleProps, data: FromStyleDataStack) => ReturnType; + parseLayer?: (data: { + value: string; + values: PropValues; + }) => PropValues; + selectedLayer?: Layer; + prepend?: boolean; + __layers?: PropValues[]; +} +/** + * + * [Layer]: layer.html + * + * + * @typedef PropertyStack + * @property {Boolean} [preview=false] Indicate if the layer should display a preview. + * @property {String|RegExp} [layerSeparator=', '] The separator used to split layer values. + * @property {String} [layerJoin=', '] Value used to join layer values. + * @property {Function} [layerLabel] Custom logic for creating layer labels. + * \n + * ```js + * layerLabel: (layer) => { + * const values = layer.getValues(); + * return `A: ${values['prop-a']} B: ${values['prop-b']}`; + * } + * ``` + * + */ +export declare class PropertyStack extends PropertyComposite { + defaults(): any; + initialize(props?: {}, opts?: {}): void; /** - * CSS for the iframe which containing the canvas, useful if you need to customize - * something inside (eg. the style of the selected component). - * @default '' + * Get all available layers. + * @returns {Array<[Layer]>} */ - canvasCss?: string; + getLayers(): Layer[]; + __getLayers(): Layers; /** - * Default command - * @default 'select-comp' + * Get layer by index. + * @param {Number} [index=0] Layer index position. + * @returns {[Layer]|null} + * @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); */ - defaultCommand?: string; + getLayer(index?: number): Layer | undefined; /** - * Show a toolbar when the component is selected - * @default true + * Get selected layer. + * @returns {[Layer] | undefined} */ - showToolbar?: boolean; + getSelectedLayer(): Layer | undefined; /** - * If true render a select of available devices - * @default true + * Select layer. + * Without a selected layer any update made on inner properties has no effect. + * @param {[Layer]} layer Layer to select + * @example + * const layer = property.getLayer(0); + * property.selectLayer(layer); */ - showDevices?: boolean; + selectLayer(layer: Layer): this; /** - * When enabled, on device change media rules won't be created - * @default false + * Select layer by index. + * @param {Number} index Index of the layer to select. + * @example + * property.selectLayerAt(1); */ - devicePreviewMode?: boolean; + selectLayerAt(index?: number): this | undefined; /** - * The condition to use for media queries, eg. 'max-width'. - * Comes handy for mobile-first cases. - * @default 'max-width' + * Move layer by index. + * @param {[Layer]} layer Layer to move. + * @param {Number} index New layer index. + * @example + * const layer = property.getLayer(1); + * property.moveLayer(layer, 0); */ - mediaCondition?: string; + moveLayer(layer: Layer, index?: number): void; /** - * Starting tag for variable inside scripts in Components - * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts - * @default '{[ ' + * Add new layer to the stack. + * @param {Object} [props={}] Custom property values to use in a new layer. + * @param {Object} [opts={}] Options + * @param {Number} [opts.at] Position index (by default the layer will be appended at the end). + * @returns {[Layer]} Added layer. + * @example + * // Add new layer at the beginning of the stack with custom values + * property.addLayer({ 'sub-prop1': 'value1', 'sub-prop2': 'value2' }, { at: 0 }); */ - tagVarStart?: string; + addLayer(props?: LayerValues, opts?: {}): Layer; /** - * Ending tag for variable inside scripts in Components - * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts - * @default ' ]}' + * Remove layer. + * @param {[Layer]} layer Layer to remove. + * @returns {[Layer]} Removed layer + * @example + * const layer = property.getLayer(0); + * property.removeLayer(layer); */ - tagVarEnd?: string; + removeLayer(layer: Layer): Layer; /** - * When false, removes empty text nodes when parsed, unless they contain a space. - * @default false + * Remove layer by index. + * @param {Number} index Index of the layer to remove + * @returns {[Layer]|null} Removed layer + * @example + * property.removeLayerAt(0); */ - keepEmptyTextNodes?: boolean; + removeLayerAt(index?: number): Layer | null; /** - * Return JS of components inside HTML from 'editor.getHtml()'. - * @default true + * Get the layer label. The label can be customized with the `layerLabel` property. + * @param {[Layer]} layer + * @returns {String} + * @example + * const layer = this.getLayer(1); + * const label = this.getLayerLabel(layer); */ - jsInHtml?: boolean; + getLayerLabel(layer: Layer): string; /** - * Enable native HTML5 drag and drop. - * @default true + * Get style object from the layer. + * @param {[Layer]} layer + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.camelCase] Return property names in camelCase. + * @param {Object} [opts.number] Limit the result of the number types, eg. `number: { min: -3, max: 3 }` + * @returns {Object} Style object */ - nativeDnD?: boolean; + getStyleFromLayer(layer: Layer, opts?: OptionStyleStack): StyleProps; /** - * Enable multiple component selection. - * @default true + * Get preview style object from the layer. + * If the property has `preview: false` the returned object will be empty. + * @param {[Layer]} layer + * @param {Object} [opts={}] Options. Same of `getStyleFromLayer` + * @returns {Object} Style object */ - multipleSelection?: boolean; + getStylePreview(layer: Layer, opts?: OptionStyleStack): {}; /** - * Pass default available options wherever `editor.getHtml()` is called. - * @default {} + * Get layer separator. + * @return {RegExp} */ - optsHtml?: HTMLGeneratorBuildOptions; + getLayerSeparator(): RegExp; + __upProperties(prop: Property, opts?: any): void; + __upLayers(m: any, c: any, o: any): void; + __upTargets(p: this, opts?: any): void; + __upTargetsStyleProps(opts?: {}): void; + __upTargetsStyle(style: StyleProps, opts: any): void; + __upSelected({ noEvent }?: { + noEvent?: boolean; + }, opts?: OptionsUpdate): void; + _up(props: Partial, opts?: OptionsUpdate): this; + __setLayers(newLayers?: PropValues[]): void; + __parseValue(value: string): Partial; + __parseLayer(value: string): PropValues; + __getLayersFromStyle(style?: StyleProps): any[] | null; + getStyle(opts?: OptionStyleStack): StyleProps; + getStyleFromLayers(opts?: OptionStyleStack): StyleProps; + __getJoinLayers(): string; + __getFullValue(): string; /** - * Pass default available options wherever `editor.getCss()` is called - * @default {} + * Extended + * @private */ - optsCss?: CssGeneratorBuildOptions; + hasValue(opts?: { + noParent?: boolean; + }): boolean; /** - * 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. + * Extended + * @private */ - avoidInlineStyle?: boolean; + clear(opts?: {}): this; + __canClearProp(): boolean; +} +export type PropertyTypes = PropertyStackProps | PropertySelectProps | PropertyNumberProps; +export type StyleManagerEvent = "style:sector:add" | "style:sector:remove" | "style:sector:update" | "style:property:add" | "style:property:remove" | "style:property:update" | "style:target"; +export type StyleTarget = StyleableModel; +export type StyleModuleParam = Parameters[N]; +declare const stylesEvents: { + all: string; + sectorAdd: string; + sectorRemove: string; + sectorUpdate: string; + propertyAdd: string; + propertyRemove: string; + propertyUpdate: string; + layerSelect: string; + target: string; + custom: string; +}; +declare class StyleManager extends ItemManagerModule { + builtIn: PropertyFactory; + upAll: Debounced; + properties: typeof Properties; + events: typeof stylesEvents; + sectors: Sectors; + SectView: SectorsView; + Sector: typeof Sector; + storageKey: string; + __ctn?: HTMLElement; /** - * 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). - * @default true + * Get configuration object + * @name getConfig + * @function + * @return {Object} */ - 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. - * @default false + * Initialize module. Automatically called with a new instance of the editor + * @param {Object} config Configurations + * @private */ - clearStyles?: boolean; + constructor(em: EditorModel); + __upSel(): void; + __trgCustom(opts?: { + container?: HTMLElement; + }): void; + __trgEv(event: string, ...data: any[]): void; + __clearStateTarget(): void; + onLoad(): void; + postRender(): void; /** - * 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/GrapesJS/grapesjs/issues/1936. - */ - dragMode?: "translate" | "absolute"; + * Add new sector. If the sector with the same id already exists, that one will be returned. + * @param {String} id Sector id + * @param {Object} sector Sector definition. Check the [available properties](sector.html#properties) + * @param {Object} [options={}] Options + * @param {Number} [options.at] Position index (by default, will be appended at the end). + * @returns {[Sector]} Added Sector + * @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 + * */ + addSector(id: string, sector: SectorProperties, options?: AddOptions): Sector; /** - * 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')], - * @default [] + * Get sector by id. + * @param {String} id Sector id + * @returns {[Sector]|null} + * @example + * const sector = styleManager.getSector('mySector'); * */ - listenToEl?: HTMLElement[]; + getSector(id: string, opts?: { + warn?: boolean; + }): Sector; /** - * Import asynchronously CSS to use as icons. - * @default 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css' + * Get all sectors. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.visible] Returns only visible sectors + * @returns {Array<[Sector]>} + * @example + * const sectors = styleManager.getSectors(); * */ - cssIcons?: string; + getSectors(opts?: T): T["array"] extends true ? Sector[] : T["visible"] extends true ? Sector[] : Sectors; /** - * Experimental: don't use. - * Editor icons + * Remove sector by id. + * @param {String} id Sector id + * @returns {[Sector]} Removed sector + * @example + * const removed = styleManager.removeSector('mySector'); */ - icons?: ObjectAny; + removeSector(id: string): Sector; /** - * Configurations for I18n. + * Add new property to the sector. + * @param {String} sectorId Sector id. + * @param {Object} property Property definition. Check the [base available properties](property.html#properties) + others based on the `type` of your property. + * @param {Object} [opts={}] Options + * @param {Number} [opts.at] Position index (by default, will be appended at the end). + * @returns {[Property]|null} Added property or `null` in case the sector doesn't exist. + * @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 }); */ - i18n?: I18nConfig; + addProperty(sectorId: string, property: PropertyTypes, opts?: AddOptions): Property | undefined; /** - * Configurations for Undo Manager + * Get the property. + * @param {String} sectorId Sector id. + * @param {String} id Property id. + * @returns {[Property]|undefined} + * @example + * const property = styleManager.getProperty('mySector', 'min-height'); */ - undoManager?: UndoManagerConfig | boolean; + getProperty(sectorId: string, id: string): Property | undefined; /** - * Configurations for Asset Manager. + * Get all properties of the sector. + * @param {String} sectorId Sector id. + * @returns {Collection<[Property]>|undefined} Collection of properties + * @example + * const properties = styleManager.getProperties('mySector'); */ - assetManager?: AssetManagerConfig; + getProperties(sectorId: string): Collection> | undefined; /** - * Configurations for Canvas. + * Remove the property. + * @param {String} sectorId Sector id. + * @param {String} id Property id. + * @returns {[Property]|null} Removed property + * @example + * const property = styleManager.removeProperty('mySector', 'min-height'); */ - canvas?: CanvasConfig; + removeProperty(sectorId: string, id: string): Property | null; /** - * Configurations for Storage Manager. + * Select new target. + * The target could be a Component, CSSRule, or a CSS selector string. + * @param {[Component]|[CSSRule]|String} target + * @returns {Array<[Component]|[CSSRule]>} Array containing selected Components or CSSRules + * @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'); */ - storageManager?: StorageManagerConfig | boolean; + select(target: StyleTarget | string | (StyleTarget | string)[], opts?: { + stylable?: boolean; + component?: Component; + }): StyleTarget[]; /** - * Configurations for Rich Text Editor. + * Get the last selected target. + * By default, the Style Manager shows styles of the last selected target. + * @returns {[Component]|[CSSRule]|null} */ - richTextEditor?: RichTextEditorConfig; + getSelected(): StyleTarget | undefined; /** - * Configurations for DomComponents + * Get the array of selected targets. + * @returns {Array<[Component]|[CSSRule]>} */ - domComponents?: DomComponentsConfig; + getSelectedAll(): StyleTarget[]; /** - * Configurations for Modal Dialog. + * Get parent rules of the last selected target. + * @returns {Array<[CSSRule]>} */ - modal?: ModalConfig; + getSelectedParents(): CssRule[]; + __getStateTarget(): CssRule | undefined; /** - * Configurations for Code Manager. + * Update selected targets with a custom style. + * @param {Object} style Style object + * @param {Object} [opts={}] Options + * @example + * styleManager.addStyleTargets({ color: 'red' }); */ - codeManager?: CodeManagerConfig; + addStyleTargets(style: StyleProps, opts: any): void; /** - * Configurations for Panels. + * Return built-in property definition + * @param {String} prop Property name. + * @returns {Object|null} Property definition. + * @example + * const widthPropDefinition = styleManager.getBuiltIn('width'); */ - panels?: PanelsConfig; + getBuiltIn(prop: string): PropertyProps | undefined; /** - * Configurations for Commands. + * Get all the available built-in property definitions. + * @returns {Object} */ - commands?: CommandsConfig; + getBuiltInAll(): Record; /** - * Configurations for Css Composer. + * Add built-in property definition. + * If the property exists already, it will extend it. + * @param {String} prop Property name. + * @param {Object} definition Property definition. + * @returns {Object} Added property definition. + * @example + * const sector = styleManager.addBuiltIn('new-property', { + * type: 'select', + * default: 'value1', + * options: [{ id: 'value1', label: 'Some label' }, ...], + * }) */ - cssComposer?: CssComposerConfig; + addBuiltIn(prop: string, definition: Omit & { + proeperty?: "string"; + }): any; /** - * Configurations for Selector Manager. + * Get what to style inside Style Manager. If you select the component + * without classes the entity is the Component itself and all changes will + * go inside its 'style' property. Otherwise, if the selected component has + * one or more classes, the function will return the corresponding CSS Rule + * @param {Model} model + * @return {Model} + * @private */ - selectorManager?: SelectorManagerConfig; + getModelToStyle(model: any, options?: { + skipAdd?: boolean; + useClasses?: boolean; + }): any; + getParentRules(target: StyleTarget, { state, component }?: { + state?: string; + component?: Component; + }): CssRule[]; /** - * Configurations for Device Manager. + * Add new property type + * @param {string} id Type ID + * @param {Object} definition Definition of the type. + * @example + * styleManager.addType('my-custom-prop', { + * // Create UI + * create({ props, change }) { + * const el = document.createElement('div'); + * el.innerHTML = ''; + * 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() {} + *}) */ - deviceManager?: DeviceManagerConfig; + addType(id: string, definition: CustomPropertyView): void; /** - * Configurations for Style Manager. + * Get type + * @param {string} id Type ID + * @return {Object} Type definition + */ + getType(id: string): any; + /** + * Get all types + * @return {Array} */ - styleManager?: StyleManagerConfig; + getTypes(): any; /** - * Configurations for Block Manager. + * Create new UI property from type (Experimental) + * @param {string} id Type ID + * @param {Object} [options={}] Options + * @param {Object} [options.model={}] Custom model object + * @param {Object} [options.view={}] Custom view object + * @return {PropertyView} + * @private + * @example + * const propView = styleManager.createType('number', { + * model: {units: ['px', 'rem']} + * }); + * propView.render(); + * propView.model.on('change:value', ...); + * someContainer.appendChild(propView.el); */ - blockManager?: BlockManagerConfig; + createType(id: string, { model, view }?: { + model?: {} | undefined; + view?: {} | undefined; + }): any; /** - * Configurations for Trait Manager. - */ - traitManager?: TraitManagerConfig; + * Render sectors and properties + * @return {HTMLElement} + * @private + * */ + render(): HTMLElement; + _logNoSector(sectorId: string): void; + __emitCmpStyleUpdate(style: StyleProps, opts?: { + components?: Component | Component[]; + }): void; + __upProps(opts?: {}): void; + __upProp(prop: any, style: StyleProps, parentStyles: any[], opts: any): void; + destroy(): void; +} +export interface StyleManagerConfig { /** - * Configurations for Page Manager. + * Default sectors and properties */ - pageManager?: PageManagerConfig; + sectors?: (Omit & { + properties?: (string | PropertyTypes)[]; + })[]; /** - * Configurations for Layer Manager. + * Specify the element to use as a container, string (query) or HTMLElement. + * With the empty value, nothing will be rendered. */ - layerManager?: LayerManagerConfig; + appendTo?: string | HTMLElement; /** - * Configurations for Parser module. + * Style prefix. + * @default 'sm-' */ - parser?: ParserConfig; - /** Texts **/ - textViewCode?: string; + stylePrefix?: string; /** - * Keep unused styles within the editor. + * Avoid rendering the default style manager. * @default false */ - keepUnusedStyles?: boolean; + custom?: boolean; /** - * Experimental: don't use. - * Avoid default UI styles. + * Hide the property in case it's not stylable for the + * selected component (each component has 'stylable' property). + * @deprecated */ - customUI?: boolean; - el?: HTMLElement; + hideNotStylable?: boolean; /** - * Color picker options. + * Highlight changed properties of the selected component. + * @deprecated */ - colorPicker?: ObjectAny; - pStylePrefix?: string; -} -export type EditorConfigKeys = keyof EditorConfig; -export declare class Blocks extends Collection { -} -export declare class Categories extends Collection { - /** @ts-ignore */ - add(model: (BlockCategoryProperties | Category)[] | BlockCategoryProperties | Category, opts?: AddOptions): Category; - get(id: string | Category): Category; -} -declare enum BlocksEvents { + highlightChanged?: boolean; /** - * @event `block:add` New block added to the collection. The [Block] is passed as an argument to the callback. - * @example - * editor.on('block:add', (block) => { ... }); + * Highlight computed properties of the selected component. + * @deprecated */ - add = "block:add", + highlightComputed?: boolean; /** - * @event `block:remove` Block removed from the collection. The [Block] is passed as an argument to the callback. - * @example - * editor.on('block:remove', (block) => { ... }); + * Show computed properties of the selected component, if this value + * is set to false, highlightComputed will not take effect. + * @deprecated */ - remove = "block:remove", + showComputed?: boolean; /** - * @event `block:remove:before` Event triggered before Block remove. - * @example - * editor.on('block:remove:before', (block, remove, opts) => { ... }); + * Adds the possibility to clear property value from the target style. + * @deprecated */ - removeBefore = "block:remove:before", + clearProperties?: boolean; /** - * @event `block:update` Block updated. The [Block] and the object containing changes are passed as arguments to the callback. - * @example - * editor.on('block:update', (block, updatedProps) => { ... }); + * Properties not to take in account for computed styles. + * @deprecated */ - update = "block:update", + avoidComputed?: string[]; + pStylePrefix?: string; +} +export type HTMLGeneratorBuildOptions = { /** - * @event `block:drag:start` Started dragging block. The [Block] is passed as an argument. - * @example - * editor.on('block:drag:start', (block) => { ... }); + * Remove unnecessary IDs (eg. those created automatically). */ - dragStart = "block:drag:start", + cleanId?: boolean; /** - * @event `block:drag` The block is dragging. The [Block] is passed as an argument. - * @example - * editor.on('block:drag', (block) => { ... }); + * 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. */ - drag = "block:drag", + attributes?: Record | ((component: Component, attr: Record) => Record); +}; +export type CssGeneratorBuildOptions = { /** - * @event `block:drag:stop` Dragging of the block is stopped. The dropped [Component] (if dropped successfully) and the [Block] are passed as arguments. - * @example - * editor.on('block:drag:stop', (component, block) => { ... }); + * Return an array of CssRules instead of the CSS string. */ - dragEnd = "block:drag:stop", + json?: boolean; /** - * @event `block:custom` Event to use in case of [custom Block Manager UI](https://grapesjs.com/docs/modules/Blocks.html#customization). - * @example - * editor.on('block:custom', ({ container, blocks, ... }) => { ... }); + * Return only rules matched by the passed component. */ - custom = "block:custom", + onlyMatched?: boolean; /** - * @event `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. - * @example - * editor.on('block', ({ event, model, ... }) => { ... }); + * Force keep all defined rules. Toggle on in case output looks different inside/outside of the editor. */ - all = "block" -} -export interface BlocksViewConfig { - em: EditorModel; - pStylePrefix?: string; - ignoreCategories?: boolean; - getSorter?: any; -} -declare class BlocksView extends View { - em: EditorModel; - config: BlocksViewConfig; - categories: Categories; - renderedCategories: Map; - ppfx: string; - noCatClass: string; - blockContClass: string; - catsClass: string; - catsEl?: HTMLElement; - blocksEl?: HTMLElement; - rendered?: boolean; - sorter: any; - constructor(opts: any, config: BlocksViewConfig); - __getModule(): BlockManager; - updateConfig(opts?: {}): void; + keepUnusedStyles?: boolean; + rules?: CssRule[]; + clearStyles?: boolean; +}; +export interface EditorConfig { /** - * Get sorter - * @private + * Style class name prefix. + * @default 'gjs-' */ - getSorter(): any; - onDrag(ev: Event): void; - onMove(ev: Event): void; - onDrop(component?: Component): void; - /** - * Add new model to the collection - * @param {Model} model - * @private - * */ - addTo(model: Block): void; - /** - * Render new model inside the view - * @param {Model} model - * @param {Object} fragment Fragment collection - * @private - * */ - add(model: Block, fragment?: DocumentFragment): void; - getCategoriesEl(): HTMLElement; - getBlocksEl(): HTMLElement; - append(el: HTMLElement | DocumentFragment): void; - render(): this; -} -export type BlockEvent = `${BlocksEvents}`; -declare class BlockManager extends ItemManagerModule { - blocks: Blocks; - blocksVisible: Blocks; - categories: Categories; - blocksView?: BlocksView; - _dragBlock?: Block; - _bhv?: Record; - events: typeof BlocksEvents; - Block: typeof Block; - Blocks: typeof Blocks; - Category: typeof Category; - Categories: typeof Categories; - storageKey: string; - constructor(em: EditorModel); + stylePrefix?: string; /** - * Get configuration object - * @name getConfig - * @function - * @return {Object} + * Selector which indicates where render the editor. */ - __trgCustom(): void; - __customData(): { - bm: BlockManager; - blocks: Block[]; - container: any; - dragStart: (block: Block, ev?: Event) => void; - drag: (ev: Event) => void; - dragStop: (cancel?: boolean) => void; - }; - __startDrag(block: Block, ev?: Event): void; - __drag(ev: Event): void; - __endDrag(opts?: { - component?: Component; - }): void; - __getFrameViews(): FrameView[]; - __behaviour(opts?: {}): {}; - __getBehaviour(): Record; - startDrag(block: Block, ev?: Event): void; - endDrag(cancel?: boolean): void; - postRender(): void; + container?: string | HTMLElement; /** - * Add new block. - * @param {String} id Block ID - * @param {[Block]} props Block properties - * @returns {[Block]} Added block - * @example - * blockManager.add('h1-block', { - * label: 'Heading', - * content: '

Put your title here

', - * category: 'Basic', - * attributes: { - * title: 'Insert h1 block' - * } - * }); + * If true, auto-render the content + * @default true */ - add(id: string, props: BlockProperties, opts?: {}): Block; + autorender?: boolean; /** - * Get the block by id. - * @param {String} id Block id - * @returns {[Block]} - * @example - * const block = blockManager.get('h1-block'); - * console.log(JSON.stringify(block)); - * // {label: 'Heading', content: '

Put your ...', ...} + * Array of plugins to execute on start. + * @default [] */ - get(id: string): Block; + plugins?: (string | Plugin)[]; /** - * Return all blocks. - * @returns {Collection<[Block]>} - * @example - * const blocks = blockManager.getAll(); - * console.log(JSON.stringify(blocks)); - * // [{label: 'Heading', content: '

Put your ...'}, ...] + * Custom options for plugins + * @default {} */ - getAll(): Blocks; + pluginsOpts?: Record; /** - * Return the visible collection, which containes blocks actually rendered - * @returns {Collection<[Block]>} + * Init headless editor. + * @default false */ - getAllVisible(): Blocks; + headless?: boolean; /** - * Remove block. - * @param {String|[Block]} block Block or block ID - * @returns {[Block]} Removed block - * @example - * const removed = blockManager.remove('BLOCK_ID'); - * // or by passing the Block - * const block = blockManager.get('BLOCK_ID'); - * blockManager.remove(block); + * Initial project data (JSON containing your components/styles/etc) to load. */ - remove(block: string | Block, opts?: {}): any; + projectData?: ObjectAny; /** - * Get all available categories. - * It's possible to add categories only within blocks via 'add()' method - * @return {Array|Collection} + * HTML string or object of components + * @deprecated Rely on `projectData` option + * @default '' */ - getCategories(): Categories; + components?: string; /** - * Return the Blocks container element - * @return {HTMLElement} + * CSS string or object of rules + * @deprecated Rely on `projectData` option + * @default '' */ - getContainer(): HTMLElement | undefined; + style?: string; /** - * Returns currently dragging block. - * Updated when the drag starts and cleared once it's done. - * @returns {[Block]|undefined} + * If true, will fetch HTML and CSS from the selected container. + * @deprecated + * @default false */ - getDragBlock(): Block | undefined; + fromElement?: boolean; /** - * Render blocks - * @param {Array} blocks Blocks to render, without the argument will render all global blocks - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.external] Render blocks in a new container (HTMLElement will be returned) - * @param {Boolean} [opts.ignoreCategories] Render blocks without categories - * @return {HTMLElement} Rendered element - * @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: '
Content
'} - * ]); - * - * // 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); + * Show an alert before unload the page with unsaved changes + * @default true */ - render(blocks?: Block[], opts?: { - external?: boolean; - }): HTMLElement | undefined; - destroy(): void; -} -/** - * @typedef State - * @property {String} name State name, eg. `hover`, `nth-of-type(2n)` - * @property {String} label State label, eg. `Hover`, `Even/Odd` - */ -export declare class State extends Model { - defaults(): { - name: string; - label: string; - }; + noticeOnUnload?: boolean; /** - * Get state name - * @returns {String} + * Show paddings and margins. + * @default false */ - getName(): string; + showOffsets?: boolean; /** - * Get state label. If label was not provided, the name will be returned. - * @returns {String} + * Show paddings and margins on selected component + * @default false */ - getLabel(): string; -} -declare class ClassTagsView extends View { - template({ labelInfo, labelHead, iconSync, iconAdd, pfx, ppfx }: any): string; - events(): { - "change [data-states]": string; - "click [data-add]": string; - "focusout [data-input]": string; - "keyup [data-input]": string; - "click [data-sync-style]": string; - }; - $input?: JQuery; - $addBtn?: JQuery; - $classes?: JQuery; - $btnSyncEl?: JQuery; - $states?: JQuery; - $statesC?: JQuery; - em: EditorModel; - target: EditorModel; - module: SelectorManager; - pfx: string; - ppfx: string; - stateInputId: string; - stateInputC: string; - config: any; - states: State[]; - constructor(o?: any); - syncStyle(): void; + showOffsetsSelected?: boolean; /** - * Triggered when a tag is removed from collection - * @param {Object} model Removed model - * @private + * 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. + * @default true */ - tagRemoved(model?: State): void; + forceClass?: boolean; /** - * Add new model - * @param {Object} model - * @private + * Height for the editor container + * @default '900px' */ - addNew(model: State): void; + height?: string; /** - * Start tag creation - * @param {Object} e - * @private + * Width for the editor container + * @default '100%' */ - startNewTag(): void; + width?: string; /** - * End tag creation - * @param {Object} e - * @private + * 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. + * @default ['warning', 'error'] */ - endNewTag(): void; + log?: ("debug" | "info" | "warning" | "error")[] | boolean; /** - * Checks what to do on keyup event - * @param {Object} e - * @private + * 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. + * @deprecated in favor of `config.canvas.frameStyle` + * @default '' */ - onInputKeyUp(e: KeyboardEvent): void; - checkStates(): void; + baseCss?: string; /** - * Triggered when component is changed - * @param {Object} e - * @public + * CSS that could only be seen (for instance, inside the code viewer) + * @default '* { box-sizing: border-box; } body {margin: 0;}' */ - componentChanged({ targets }?: any): void; - updateSelection(targets: Component | Component[]): Selector[]; - getCommonSelectors({ targets, opts }?: any): Selector[]; - _commonSelectors(...args: any): Selector[]; - checkSync(): void; - getTarget(): Component | undefined; - getTargets(): Component[]; + protectedCss?: string; /** - * Update states visibility. Hides states in case there is no tags - * inside collection - * @private + * CSS for the iframe which containing the canvas, useful if you need to customize + * something inside (eg. the style of the selected component). + * @default '' */ - updateStateVis(targets?: Component[] | Component): void; - __handleStateChange(): void; + canvasCss?: string; /** - * Update selector helper - * @return {this} - * @private + * Default command + * @default 'select-comp' */ - updateSelector(targets?: Component[] | Component): void; - __getName(target: Component): string; + defaultCommand?: string; /** - * Triggered when the select with states is changed - * @param {Object} e - * @private + * Show a toolbar when the component is selected + * @default true */ - stateChanged(ev: any): void; + showToolbar?: boolean; /** - * Add new tag to collection, if possible, and to the component - * @param {Object} e - * @private + * If true render a select of available devices + * @default true */ - addNewTag(value: any): void; + showDevices?: boolean; /** - * Add new object to collection - * @param {Object} model Model - * @param {Object} fragmentEl Fragment collection - * @return {Object} Object created - * @private - * */ - addToClasses(model: State, fragmentEl?: DocumentFragment): HTMLElement; + * When enabled, on device change media rules won't be created + * @default false + */ + devicePreviewMode?: boolean; /** - * Render the collection of classes - * @private + * The condition to use for media queries, eg. 'max-width'. + * Comes handy for mobile-first cases. + * @default 'max-width' + */ + mediaCondition?: string; + /** + * Starting tag for variable inside scripts in Components + * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts + * @default '{[ ' */ - renderClasses(): void; + tagVarStart?: string; /** - * Return classes element - * @return {HTMLElement} - * @private + * Ending tag for variable inside scripts in Components + * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts + * @default ' ]}' */ - getClasses(): JQuery; + tagVarEnd?: string; /** - * Return states element - * @return {HTMLElement} - * @private + * When false, removes empty text nodes when parsed, unless they contain a space. + * @default false */ - getStates(): JQuery; + keepEmptyTextNodes?: boolean; /** - * Return states container element - * @return {HTMLElement} - * @private + * Return JS of components inside HTML from 'editor.getHtml()'. + * @default true */ - getStatesC(): JQuery; - renderStates(): void; - render(): this; -} -export declare class Sectors extends Collection { - em: EditorModel; - module: any; - initialize(prop: any, opts?: { - em?: EditorModel; - module?: any; - }): void; - /** @ts-ignore */ - model(props: any, opts?: {}): Sector; - onReset(models: any, opts?: { - previousModels?: Sector[]; - }): void; -} -export declare const Properties: any; -export type Option = { - id: string; - label?: string; -}; -declare class PropertyFactory { - props: Record; - typeNumber: string; - typeColor: string; - typeRadio: string; - typeSelect: string; - typeFile: string; - typeSlider: string; - typeComposite: string; - typeStack: string; - unitsSize: string[]; - unitsSizeNoPerc: string[]; - unitsTime: string[]; - unitsAngle: string[]; - fixedValues: string[]; - optsBgSize: Option[]; - optsBgAttach: Option[]; - optsBgRepeat: Option[]; - optsWrap: Option[]; - optsOverflow: Option[]; - optsDir: Option[]; - opstDisplay: Option[]; - optsTransitFn: Option[]; - optsCursor: Option[]; - optsFloat: Option[]; - optsPos: Option[]; - optsTextAlign: Option[]; - optsFlexAlign: Option[]; - optsJustCont: Option[]; - optsAlignCont: Option[]; - optsAlignSelf: Option[]; - optsTransitProp: Option[]; - optsBorderStyle: Option[]; - optsBgPos: Option[]; - optsWeight: Option[]; - optsShadowType: Option[]; - optsFonts: Option[]; - fixedFontSizes: string[]; - fixedLetSpace: string[]; - requireFlex: Record; - constructor(); - __sub(items: (string | PropertyProps)[]): () => PropertyProps[]; - init(): this; - add(property: string, def?: Record, opts?: { - from?: string; - }): any; - get(prop: string): PropertyProps | undefined; + jsInHtml?: boolean; /** - * Build props object by their name - * @param {Array|string} props Array of properties name - * @return {Array} + * Enable native HTML5 drag and drop. + * @default true */ - build(props: string | string[]): PropertyProps[]; -} -declare class SectorsView extends View { - pfx: string; - ppfx: string; - config: StyleManagerConfig; - module: any; - constructor(o?: { - module?: any; - config?: StyleManagerConfig; - el?: HTMLElement; - em?: EditorModel; - collection?: Sectors; - }); - remove(): this; - addTo(model: Sector, c: any, opts?: {}): void; - addToCollection(model: Sector, fragmentEl: DocumentFragment | null, opts?: { - at?: number; - }): HTMLElement; - render(): this; -} -export interface ICustomPropertyView { - create?: (data: ReturnType) => any; - destroy?: (data: ReturnType) => any; - update?: (data: ReturnType & { - value: string; - }) => any; - emit?: (data: ReturnType, ...args: any) => any; - unset?: (data: ReturnType) => any; -} -export type CustomPropertyView = ICustomPropertyView & T & ThisType; -declare class PropertyView extends View { - em: EditorModel; - pfx: string; - ppfx: string; - config: any; - parent?: PropertyView; - __destroyFn: Function; - create?: Function; - destroy?: Function; - update?: Function; - emit?: Function; - unset?: Function; - clearEl?: HTMLElement; - createdEl?: HTMLElement; - input?: HTMLInputElement; - $input?: any; - constructor(o?: {}); - events(): { - change: string; - "click [data-clear-style]": string; - }; - template(model: any): string; - templateLabel(model: Property): string; - templateInput(model: Property): string; - remove(): this; + nativeDnD?: boolean; /** - * Triggers when the status changes. The status indicates if the value of - * the proprerty is changed or inherited - * @private + * Enable multiple component selection. + * @default true */ - updateStatus(): void; + multipleSelection?: boolean; /** - * Clear the property from the target + * Pass default available options wherever `editor.getHtml()` is called. + * @default {} */ - clear(ev: Event): void; + optsHtml?: HTMLGeneratorBuildOptions; /** - * Get clear element - * @return {HTMLElement} + * Pass default available options wherever `editor.getCss()` is called + * @default {} */ - getClearEl(): HTMLElement; + optsCss?: CssGeneratorBuildOptions; /** - * Triggers when the value of element input/s is changed, so have to update - * the value of the model which will propogate those changes to the target + * 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. */ - inputValueChanged(ev: any): void; - onValueChange(m: any, val: any, opt?: any): void; + avoidInlineStyle?: boolean; /** - * Update the element input. - * Usually the value is a result of `model.getFullValue()` - * @param {String} value The value from the model - * */ - setValue(value: string): void; - __setValueInput(value: string): void; - getInputEl(): HTMLInputElement; - updateVisibility(): void; - clearCached(): void; - __unset(): void; - __update(value: string): void; - __change(...args: any): void; - __updateStyle(value: string | StyleProps, { complete, partial, ...opts }?: any): void; - _getClbOpts(): { - el: HTMLElement; - createdEl: HTMLElement | undefined; - property: Property; - props: Partial; - change: (...args: any) => void; - updateStyle: (value: string | StyleProps, { complete, partial, ...opts }?: any) => void; - }; - render(): this; - onRender(): void; -} -declare class PropertiesView extends View { - config?: any; - pfx: string; - properties: PropertyView[]; - parent?: PropertyView; - constructor(o: any); - addTo(model: any, coll: any, opts: any): void; - add(model: any, frag: DocumentFragment | null, opts?: any): void; - remove(): this; - clearItems(): void; - render(): this; -} -declare class PropertyCompositeView extends PropertyView { - props?: PropertiesView; - templateInput(): string; - remove(): this; - onValueChange(): void; - onRender(): void; - clearCached(): void; -} -declare class LayersView extends View { - pfx: string; - ppfx: string; - config: any; - propertyView: PropertyStackView; - items: LayerView[]; - sorter: any; - constructor(o: any); - addTo(model: Layer): void; - addToCollection(model: Layer, fragmentEl: DocumentFragment | null, index?: number): HTMLElement; - reset(coll: any, opts: any): void; - remove(): this; - clearItems(): void; - render(): this; -} -declare class PropertyStackView extends PropertyCompositeView { - model: PropertyStack; - layersView?: LayersView; - events(): { - "click [data-add-layer]": string; - change: string; - "click [data-clear-style]": string; - }; - templateInput(): string; - init(): void; - addLayer(): void; + * 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). + * @default true + */ + avoidDefaults?: boolean; /** - * There is no need to handle input update by the property itself, - * this will be done by layers - * @private + * (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. + * @default false */ - setValue(): void; - remove(): this; - clearCached(): void; - onRender(): void; -} -declare class LayerView extends View { - pfx: string; - ppfx: string; - em: EditorModel; - propertyView: PropertyStackView; - propsWrapEl?: HTMLElement; - previewEl?: HTMLElement; - labelEl?: HTMLElement; - sorter: any; - config: any; - events(): { - click: string; - "click [data-close-layer]": string; - "mousedown [data-move-layer]": string; - "touchstart [data-move-layer]": string; - }; - template(): string; - initialize(o?: any): void; - initSorter(): void; - removeItem(ev: Event): void; - select(): void; - getPropertiesWrapper(): HTMLElement; - getPreviewEl(): HTMLElement; - getLabelEl(): HTMLElement; - updateLabel(): void; - updateVisibility(): void; - render(): this; -} -export type LayerValues = Record; -export interface LayerProps { - values: LayerValues; -} -declare class Layer extends Model { - prop: any; - view?: LayerView; - defaults(): { - values: {}; - }; - initialize(): void; + clearStyles?: boolean; /** - * Get layer id. - * @returns {String} + * 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/GrapesJS/grapesjs/issues/1936. */ - getId(): string; + dragMode?: "translate" | "absolute"; /** - * Get layer index. - * @returns {Number} + * 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')], + * @default [] + * */ + listenToEl?: HTMLElement[]; + /** + * Import asynchronously CSS to use as icons. + * @default 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css' + * */ + cssIcons?: string; + /** + * Experimental: don't use. + * Editor icons */ - getIndex(): number; + icons?: ObjectAny; /** - * Get layer values. - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.camelCase] Return property names in camelCase. - * @returns {Object} + * Configurations for I18n. */ - getValues(opts?: { - camelCase?: boolean; - }): LayerValues; + i18n?: I18nConfig; /** - * Get layer label. - * @returns {String} + * Configurations for Undo Manager */ - getLabel(): string; + undoManager?: UndoManagerConfig | boolean; /** - * Check if the layer is selected. - * @returns {Boolean} + * Configurations for Asset Manager. */ - isSelected(): boolean; + assetManager?: AssetManagerConfig; /** - * Select the layer. + * Configurations for Canvas. */ - select(): any; + canvas?: CanvasConfig; /** - * Remove the layer. + * Configurations for Storage Manager. */ - remove(): any; + storageManager?: StorageManagerConfig | boolean; /** - * Move layer to a new index. - * @param {Number} index New index + * Configurations for Rich Text Editor. */ - move(index: number): any; + richTextEditor?: RichTextEditorConfig; /** - * Get style object for the preview. - * @param {Object} [opts={}] Options. Same of `PropertyStack.getStyleFromLayer` - * @returns {Object} Style object + * Configurations for DomComponents */ - getStylePreview(opts?: OptionStyleStack): Record; + domComponents?: DomComponentsConfig; /** - * Check if the property has the preview enabled for this layer. - * @returns {Boolean} + * Configurations for Modal Dialog. */ - hasPreview(): boolean; - upValues(props?: LayerValues): this; -} -declare class Layers extends Collection { - prop: any; - initialize(p: any, opts?: { - prop?: any; - }): void; -} -export type ToStyleDataStack = Omit & { - joinLayers: string; - layer: Layer; - property: PropertyStack; -}; -export type FromStyleDataStack = Omit & { - property: PropertyStack; - separatorLayers: RegExp; -}; -export type OptionStyleStack = OptionsStyle & { - number?: { - min?: number; - max?: number; - }; -}; -/** @private */ -export interface PropertyStackProps extends Omit { - layers?: LayerProps[]; + modal?: ModalConfig; /** - * The separator used to split layer values. + * Configurations for Code Manager. */ - layerSeparator?: string | RegExp; + codeManager?: CodeManagerConfig; /** - * Value used to join layer values. + * Configurations for Panels. */ - layerJoin?: string; + panels?: PanelsConfig; /** - * Indicate if the layer should display a preview. + * Configurations for Commands. */ - preview?: boolean; + commands?: CommandsConfig; /** - * Custom logic for creating layer labels. + * Configurations for Css Composer. */ - layerLabel?: (layer: Layer, data: { - index: number; - values: LayerValues; - property: PropertyStack; - }) => string; - toStyle?: (values: PropValues, data: ToStyleDataStack) => ReturnType; - fromStyle?: (style: StyleProps, data: FromStyleDataStack) => ReturnType; - parseLayer?: (data: { - value: string; - values: PropValues; - }) => PropValues; - selectedLayer?: Layer; - prepend?: boolean; - __layers?: PropValues[]; -} -/** - * - * [Layer]: layer.html - * - * - * @typedef PropertyStack - * @property {Boolean} [preview=false] Indicate if the layer should display a preview. - * @property {String|RegExp} [layerSeparator=', '] The separator used to split layer values. - * @property {String} [layerJoin=', '] Value used to join layer values. - * @property {Function} [layerLabel] Custom logic for creating layer labels. - * \n - * ```js - * layerLabel: (layer) => { - * const values = layer.getValues(); - * return `A: ${values['prop-a']} B: ${values['prop-b']}`; - * } - * ``` - * - */ -export declare class PropertyStack extends PropertyComposite { - defaults(): any; - initialize(props?: {}, opts?: {}): void; + cssComposer?: CssComposerConfig; /** - * Get all available layers. - * @returns {Array<[Layer]>} + * Configurations for Selector Manager. */ - getLayers(): Layer[]; - __getLayers(): Layers; + selectorManager?: SelectorManagerConfig; /** - * Get layer by index. - * @param {Number} [index=0] Layer index position. - * @returns {[Layer]|null} - * @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); + * Configurations for Device Manager. + */ + deviceManager?: DeviceManagerConfig; + /** + * Configurations for Style Manager. + */ + styleManager?: StyleManagerConfig; + /** + * Configurations for Block Manager. + */ + blockManager?: BlockManagerConfig; + /** + * Configurations for Trait Manager. + */ + traitManager?: TraitManagerConfig; + /** + * Configurations for Page Manager. + */ + pageManager?: PageManagerConfig; + /** + * Configurations for Layer Manager. + */ + layerManager?: LayerManagerConfig; + /** + * Configurations for Parser module. + */ + parser?: ParserConfig; + /** Texts **/ + textViewCode?: string; + /** + * Keep unused styles within the editor. + * @default false */ - getLayer(index?: number): Layer | undefined; + keepUnusedStyles?: boolean; /** - * Get selected layer. - * @returns {[Layer] | undefined} + * Experimental: don't use. + * Avoid default UI styles. */ - getSelectedLayer(): Layer | undefined; + customUI?: boolean; + el?: HTMLElement; /** - * Select layer. - * Without a selected layer any update made on inner properties has no effect. - * @param {[Layer]} layer Layer to select - * @example - * const layer = property.getLayer(0); - * property.selectLayer(layer); + * Color picker options. */ - selectLayer(layer: Layer): this; + colorPicker?: ObjectAny; + pStylePrefix?: string; +} +export type EditorConfigKeys = keyof EditorConfig; +export interface BlocksByCategory extends ItemsByCategory { +} +declare enum BlocksEvents { /** - * Select layer by index. - * @param {Number} index Index of the layer to select. + * @event `block:add` New block added to the collection. The [Block] is passed as an argument to the callback. * @example - * property.selectLayerAt(1); + * editor.on('block:add', (block) => { ... }); */ - selectLayerAt(index?: number): this | undefined; + add = "block:add", /** - * Move layer by index. - * @param {[Layer]} layer Layer to move. - * @param {Number} index New layer index. + * @event `block:remove` Block removed from the collection. The [Block] is passed as an argument to the callback. * @example - * const layer = property.getLayer(1); - * property.moveLayer(layer, 0); + * editor.on('block:remove', (block) => { ... }); */ - moveLayer(layer: Layer, index?: number): void; + remove = "block:remove", /** - * Add new layer to the stack. - * @param {Object} [props={}] Custom property values to use in a new layer. - * @param {Object} [opts={}] Options - * @param {Number} [opts.at] Position index (by default the layer will be appended at the end). - * @returns {[Layer]} Added layer. + * @event `block:remove:before` Event triggered before Block remove. * @example - * // Add new layer at the beginning of the stack with custom values - * property.addLayer({ 'sub-prop1': 'value1', 'sub-prop2': 'value2' }, { at: 0 }); + * editor.on('block:remove:before', (block, remove, opts) => { ... }); */ - addLayer(props?: LayerValues, opts?: {}): Layer; + removeBefore = "block:remove:before", /** - * Remove layer. - * @param {[Layer]} layer Layer to remove. - * @returns {[Layer]} Removed layer + * @event `block:update` Block updated. The [Block] and the object containing changes are passed as arguments to the callback. * @example - * const layer = property.getLayer(0); - * property.removeLayer(layer); + * editor.on('block:update', (block, updatedProps) => { ... }); */ - removeLayer(layer: Layer): Layer; + update = "block:update", /** - * Remove layer by index. - * @param {Number} index Index of the layer to remove - * @returns {[Layer]|null} Removed layer + * @event `block:drag:start` Started dragging block. The [Block] is passed as an argument. * @example - * property.removeLayerAt(0); + * editor.on('block:drag:start', (block) => { ... }); */ - removeLayerAt(index?: number): Layer | null; + dragStart = "block:drag:start", /** - * Get the layer label. The label can be customized with the `layerLabel` property. - * @param {[Layer]} layer - * @returns {String} + * @event `block:drag` The block is dragging. The [Block] is passed as an argument. * @example - * const layer = this.getLayer(1); - * const label = this.getLayerLabel(layer); + * editor.on('block:drag', (block) => { ... }); */ - getLayerLabel(layer: Layer): string; + drag = "block:drag", /** - * Get style object from the layer. - * @param {[Layer]} layer - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.camelCase] Return property names in camelCase. - * @param {Object} [opts.number] Limit the result of the number types, eg. `number: { min: -3, max: 3 }` - * @returns {Object} Style object + * @event `block:drag:stop` Dragging of the block is stopped. The dropped [Component] (if dropped successfully) and the [Block] are passed as arguments. + * @example + * editor.on('block:drag:stop', (component, block) => { ... }); */ - getStyleFromLayer(layer: Layer, opts?: OptionStyleStack): StyleProps; + dragEnd = "block:drag:stop", /** - * Get preview style object from the layer. - * If the property has `preview: false` the returned object will be empty. - * @param {[Layer]} layer - * @param {Object} [opts={}] Options. Same of `getStyleFromLayer` - * @returns {Object} Style object + * @event `block:custom` Event to use in case of [custom Block Manager UI](https://grapesjs.com/docs/modules/Blocks.html#customization). + * @example + * editor.on('block:custom', ({ container, blocks, ... }) => { ... }); */ - getStylePreview(layer: Layer, opts?: OptionStyleStack): {}; + custom = "block:custom", /** - * Get layer separator. - * @return {RegExp} + * @event `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. + * @example + * editor.on('block', ({ event, model, ... }) => { ... }); */ - getLayerSeparator(): RegExp; - __upProperties(prop: Property, opts?: any): void; - __upLayers(m: any, c: any, o: any): void; - __upTargets(p: this, opts?: any): void; - __upTargetsStyleProps(opts?: {}): void; - __upTargetsStyle(style: StyleProps, opts: any): void; - __upSelected({ noEvent }?: { - noEvent?: boolean; - }, opts?: OptionsUpdate): void; - _up(props: Partial, opts?: OptionsUpdate): this; - __setLayers(newLayers?: PropValues[]): void; - __parseValue(value: string): Partial; - __parseLayer(value: string): PropValues; - __getLayersFromStyle(style?: StyleProps): any[] | null; - getStyle(opts?: OptionStyleStack): StyleProps; - getStyleFromLayers(opts?: OptionStyleStack): StyleProps; - __getJoinLayers(): string; - __getFullValue(): string; + all = "block" +} +export interface BlocksViewConfig { + em: EditorModel; + pStylePrefix?: string; + ignoreCategories?: boolean; + getSorter?: any; +} +declare class BlocksView extends View { + em: EditorModel; + config: BlocksViewConfig; + categories: Categories; + renderedCategories: Map; + ppfx: string; + noCatClass: string; + blockContClass: string; + catsClass: string; + catsEl?: HTMLElement; + blocksEl?: HTMLElement; + rendered?: boolean; + sorter: any; + constructor(opts: any, config: BlocksViewConfig); + __getModule(): BlockManager; + updateConfig(opts?: {}): void; /** - * Extended + * Get sorter * @private */ - hasValue(opts?: { - noParent?: boolean; - }): boolean; + getSorter(): any; + onDrag(ev: Event): void; + onMove(ev: Event): void; + onDrop(component?: Component): void; /** - * Extended + * Add new model to the collection + * @param {Model} model * @private - */ - clear(opts?: {}): this; - __canClearProp(): boolean; + * */ + addTo(model: Block): void; + /** + * Render new model inside the view + * @param {Model} model + * @param {Object} fragment Fragment collection + * @private + * */ + add(model: Block, fragment?: DocumentFragment): void; + getCategoriesEl(): HTMLElement; + getBlocksEl(): HTMLElement; + append(el: HTMLElement | DocumentFragment): void; + render(): this; } -export type PropertyTypes = PropertyStackProps | PropertySelectProps | PropertyNumberProps; -export type StyleManagerEvent = "style:sector:add" | "style:sector:remove" | "style:sector:update" | "style:property:add" | "style:property:remove" | "style:property:update" | "style:target"; -export type StyleTarget = StyleableModel; -export type StyleModuleParam = Parameters[N]; -declare const stylesEvents: { - all: string; - sectorAdd: string; - sectorRemove: string; - sectorUpdate: string; - propertyAdd: string; - propertyRemove: string; - propertyUpdate: string; - layerSelect: string; - target: string; - custom: string; -}; -declare class StyleManager extends ItemManagerModule { - builtIn: PropertyFactory; - upAll: Debounced; - properties: typeof Properties; - events: typeof stylesEvents; - sectors: Sectors; - SectView: SectorsView; - Sector: typeof Sector; +export type BlockEvent = `${BlocksEvents}`; +declare class BlockManager extends ItemManagerModule { + blocks: Blocks; + blocksVisible: Blocks; + categories: Categories; + blocksView?: BlocksView; + _dragBlock?: Block; + _bhv?: Record; + events: typeof BlocksEvents; + Block: typeof Block; + Blocks: typeof Blocks; + Category: typeof Category; + Categories: typeof Categories; storageKey: string; - __ctn?: HTMLElement; + constructor(em: EditorModel); /** * Get configuration object * @name getConfig * @function * @return {Object} */ - /** - * Initialize module. Automatically called with a new instance of the editor - * @param {Object} config Configurations - * @private - */ - constructor(em: EditorModel); - __upSel(): void; - __trgCustom(opts?: { - container?: HTMLElement; + __trgCustom(): void; + __customData(): { + bm: BlockManager; + blocks: Block[]; + container: any; + dragStart: (block: Block, ev?: Event) => void; + drag: (ev: Event) => void; + dragStop: (cancel?: boolean) => void; + }; + __startDrag(block: Block, ev?: Event): void; + __drag(ev: Event): void; + __endDrag(opts?: { + component?: Component; }): void; - __trgEv(event: string, ...data: any[]): void; - __clearStateTarget(): void; - onLoad(): void; - postRender(): void; - /** - * Add new sector. If the sector with the same id already exists, that one will be returned. - * @param {String} id Sector id - * @param {Object} sector Sector definition. Check the [available properties](sector.html#properties) - * @param {Object} [options={}] Options - * @param {Number} [options.at] Position index (by default, will be appended at the end). - * @returns {[Sector]} Added Sector - * @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 - * */ - addSector(id: string, sector: SectorProperties, options?: AddOptions): Sector; + __getFrameViews(): FrameView[]; + __behaviour(opts?: {}): {}; + __getBehaviour(): Record; + startDrag(block: Block, ev?: Event): void; + endDrag(cancel?: boolean): void; + postRender(): void; /** - * Get sector by id. - * @param {String} id Sector id - * @returns {[Sector]|null} + * Add new block. + * @param {String} id Block ID + * @param {[Block]} props Block properties + * @returns {[Block]} Added block * @example - * const sector = styleManager.getSector('mySector'); - * */ - getSector(id: string, opts?: { - warn?: boolean; - }): Sector; + * blockManager.add('h1-block', { + * label: 'Heading', + * content: '

Put your title here

', + * category: 'Basic', + * attributes: { + * title: 'Insert h1 block' + * } + * }); + */ + add(id: string, props: BlockProperties, opts?: {}): Block; /** - * Get all sectors. - * @param {Object} [opts={}] Options - * @param {Boolean} [opts.visible] Returns only visible sectors - * @returns {Array<[Sector]>} + * Get the block by id. + * @param {String} id Block id + * @returns {[Block]} * @example - * const sectors = styleManager.getSectors(); - * */ - getSectors(opts?: T): T["array"] extends true ? Sector[] : T["visible"] extends true ? Sector[] : Sectors; + * const block = blockManager.get('h1-block'); + * console.log(JSON.stringify(block)); + * // {label: 'Heading', content: '

Put your ...', ...} + */ + get(id: string): Block; /** - * Remove sector by id. - * @param {String} id Sector id - * @returns {[Sector]} Removed sector + * Return all blocks. + * @returns {Collection<[Block]>} * @example - * const removed = styleManager.removeSector('mySector'); + * const blocks = blockManager.getAll(); + * console.log(JSON.stringify(blocks)); + * // [{label: 'Heading', content: '

Put your ...'}, ...] */ - removeSector(id: string): Sector; + getAll(): Blocks; /** - * Add new property to the sector. - * @param {String} sectorId Sector id. - * @param {Object} property Property definition. Check the [base available properties](property.html#properties) + others based on the `type` of your property. - * @param {Object} [opts={}] Options - * @param {Number} [opts.at] Position index (by default, will be appended at the end). - * @returns {[Property]|null} Added property or `null` in case the sector doesn't exist. - * @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 }); + * Return the visible collection, which containes blocks actually rendered + * @returns {Collection<[Block]>} */ - addProperty(sectorId: string, property: PropertyTypes, opts?: AddOptions): Property | undefined; + getAllVisible(): Blocks; /** - * Get the property. - * @param {String} sectorId Sector id. - * @param {String} id Property id. - * @returns {[Property]|undefined} + * Remove block. + * @param {String|[Block]} block Block or block ID + * @returns {[Block]} Removed block * @example - * const property = styleManager.getProperty('mySector', 'min-height'); + * const removed = blockManager.remove('BLOCK_ID'); + * // or by passing the Block + * const block = blockManager.get('BLOCK_ID'); + * blockManager.remove(block); */ - getProperty(sectorId: string, id: string): Property | undefined; + remove(block: string | Block, opts?: {}): any; /** - * Get all properties of the sector. - * @param {String} sectorId Sector id. - * @returns {Collection<[Property]>|undefined} Collection of properties - * @example - * const properties = styleManager.getProperties('mySector'); + * Get all available categories. + * It's possible to add categories only within blocks via 'add()' method + * @return {Array|Collection} */ - getProperties(sectorId: string): Collection> | undefined; + getCategories(): Categories; /** - * Remove the property. - * @param {String} sectorId Sector id. - * @param {String} id Property id. - * @returns {[Property]|null} Removed property + * Return the Blocks container element + * @return {HTMLElement} + */ + getContainer(): HTMLElement | undefined; + /** + * Returns currently dragging block. + * Updated when the drag starts and cleared once it's done. + * @returns {[Block]|undefined} + */ + getDragBlock(): Block | undefined; + /** + * Get blocks by category. * @example - * const property = styleManager.removeProperty('mySector', 'min-height'); + * blockManager.getBlocksByCategory(); + * // Returns an array of items of this type + * // > { category?: Category; items: Block[] } + * + * // NOTE: The item without category is the one containing blocks without category. */ - removeProperty(sectorId: string, id: string): Property | null; + getBlocksByCategory(): BlocksByCategory[]; /** - * Select new target. - * The target could be a Component, CSSRule, or a CSS selector string. - * @param {[Component]|[CSSRule]|String} target - * @returns {Array<[Component]|[CSSRule]>} Array containing selected Components or CSSRules + * Render blocks + * @param {Array} blocks Blocks to render, without the argument will render all global blocks + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.external] Render blocks in a new container (HTMLElement will be returned) + * @param {Boolean} [opts.ignoreCategories] Render blocks without categories + * @return {HTMLElement} Rendered element * @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); + * // Render all blocks (inside the global collection) + * blockManager.render(); * - * // Set as a target the CSS selector - * styleManager.select('.btn > span'); + * // 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: '
Content
'} + * ]); + * + * // 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); */ - select(target: StyleTarget | string | (StyleTarget | string)[], opts?: { - stylable?: boolean; - component?: Component; - }): StyleTarget[]; + render(blocks?: Block[], opts?: { + external?: boolean; + }): HTMLElement | undefined; + destroy(): void; +} +/** + * @typedef State + * @property {String} name State name, eg. `hover`, `nth-of-type(2n)` + * @property {String} label State label, eg. `Hover`, `Even/Odd` + */ +export declare class State extends Model { + defaults(): { + name: string; + label: string; + }; /** - * Get the last selected target. - * By default, the Style Manager shows styles of the last selected target. - * @returns {[Component]|[CSSRule]|null} + * Get state name + * @returns {String} */ - getSelected(): StyleTarget | undefined; + getName(): string; /** - * Get the array of selected targets. - * @returns {Array<[Component]|[CSSRule]>} + * Get state label. If label was not provided, the name will be returned. + * @returns {String} */ - getSelectedAll(): StyleTarget[]; + getLabel(): string; +} +declare class ClassTagsView extends View { + template({ labelInfo, labelHead, iconSync, iconAdd, pfx, ppfx }: any): string; + events(): { + "change [data-states]": string; + "click [data-add]": string; + "focusout [data-input]": string; + "keyup [data-input]": string; + "click [data-sync-style]": string; + }; + $input?: JQuery; + $addBtn?: JQuery; + $classes?: JQuery; + $btnSyncEl?: JQuery; + $states?: JQuery; + $statesC?: JQuery; + em: EditorModel; + target: EditorModel; + module: SelectorManager; + pfx: string; + ppfx: string; + stateInputId: string; + stateInputC: string; + config: any; + states: State[]; + constructor(o?: any); + syncStyle(): void; /** - * Get parent rules of the last selected target. - * @returns {Array<[CSSRule]>} + * Triggered when a tag is removed from collection + * @param {Object} model Removed model + * @private */ - getSelectedParents(): CssRule[]; - __getStateTarget(): CssRule | undefined; + tagRemoved(model?: State): void; /** - * Update selected targets with a custom style. - * @param {Object} style Style object - * @param {Object} [opts={}] Options - * @example - * styleManager.addStyleTargets({ color: 'red' }); + * Add new model + * @param {Object} model + * @private */ - addStyleTargets(style: StyleProps, opts: any): void; + addNew(model: State): void; /** - * Return built-in property definition - * @param {String} prop Property name. - * @returns {Object|null} Property definition. - * @example - * const widthPropDefinition = styleManager.getBuiltIn('width'); + * Start tag creation + * @param {Object} e + * @private + */ + startNewTag(): void; + /** + * End tag creation + * @param {Object} e + * @private + */ + endNewTag(): void; + /** + * Checks what to do on keyup event + * @param {Object} e + * @private + */ + onInputKeyUp(e: KeyboardEvent): void; + checkStates(): void; + /** + * Triggered when component is changed + * @param {Object} e + * @public */ - getBuiltIn(prop: string): PropertyProps | undefined; + componentChanged({ targets }?: any): void; + updateSelection(targets: Component | Component[]): Selector[]; + getCommonSelectors({ targets, opts }?: any): Selector[]; + _commonSelectors(...args: any): Selector[]; + checkSync(): void; + getTarget(): Component | undefined; + getTargets(): Component[]; /** - * Get all the available built-in property definitions. - * @returns {Object} + * Update states visibility. Hides states in case there is no tags + * inside collection + * @private */ - getBuiltInAll(): Record; + updateStateVis(targets?: Component[] | Component): void; + __handleStateChange(): void; /** - * Add built-in property definition. - * If the property exists already, it will extend it. - * @param {String} prop Property name. - * @param {Object} definition Property definition. - * @returns {Object} Added property definition. - * @example - * const sector = styleManager.addBuiltIn('new-property', { - * type: 'select', - * default: 'value1', - * options: [{ id: 'value1', label: 'Some label' }, ...], - * }) + * Update selector helper + * @return {this} + * @private */ - addBuiltIn(prop: string, definition: Omit & { - proeperty?: "string"; - }): any; + updateSelector(targets?: Component[] | Component): void; + __getName(target: Component): string; /** - * Get what to style inside Style Manager. If you select the component - * without classes the entity is the Component itself and all changes will - * go inside its 'style' property. Otherwise, if the selected component has - * one or more classes, the function will return the corresponding CSS Rule - * @param {Model} model - * @return {Model} + * Triggered when the select with states is changed + * @param {Object} e * @private */ - getModelToStyle(model: any, options?: { - skipAdd?: boolean; - useClasses?: boolean; - }): any; - getParentRules(target: StyleTarget, { state, component }?: { - state?: string; - component?: Component; - }): CssRule[]; + stateChanged(ev: any): void; /** - * Add new property type - * @param {string} id Type ID - * @param {Object} definition Definition of the type. - * @example - * styleManager.addType('my-custom-prop', { - * // Create UI - * create({ props, change }) { - * const el = document.createElement('div'); - * el.innerHTML = ''; - * 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() {} - *}) + * Add new tag to collection, if possible, and to the component + * @param {Object} e + * @private */ - addType(id: string, definition: CustomPropertyView): void; + addNewTag(value: any): void; /** - * Get type - * @param {string} id Type ID - * @return {Object} Type definition + * Add new object to collection + * @param {Object} model Model + * @param {Object} fragmentEl Fragment collection + * @return {Object} Object created + * @private + * */ + addToClasses(model: State, fragmentEl?: DocumentFragment): HTMLElement; + /** + * Render the collection of classes + * @private */ - getType(id: string): any; + renderClasses(): void; /** - * Get all types - * @return {Array} + * Return classes element + * @return {HTMLElement} + * @private */ - getTypes(): any; + getClasses(): JQuery; /** - * Create new UI property from type (Experimental) - * @param {string} id Type ID - * @param {Object} [options={}] Options - * @param {Object} [options.model={}] Custom model object - * @param {Object} [options.view={}] Custom view object - * @return {PropertyView} + * Return states element + * @return {HTMLElement} * @private - * @example - * const propView = styleManager.createType('number', { - * model: {units: ['px', 'rem']} - * }); - * propView.render(); - * propView.model.on('change:value', ...); - * someContainer.appendChild(propView.el); */ - createType(id: string, { model, view }?: { - model?: {} | undefined; - view?: {} | undefined; - }): any; + getStates(): JQuery; /** - * Render sectors and properties - * @return {HTMLElement} + * Return states container element + * @return {HTMLElement} * @private - * */ - render(): HTMLElement; - _logNoSector(sectorId: string): void; - __emitCmpStyleUpdate(style: StyleProps, opts?: { - components?: Component | Component[]; - }): void; - __upProps(opts?: {}): void; - __upProp(prop: any, style: StyleProps, parentStyles: any[], opts: any): void; - destroy(): void; + */ + getStatesC(): JQuery; + renderStates(): void; + render(): this; } export type SelectorEvent = "selector:add" | "selector:remove" | "selector:update" | "selector:state" | "selector"; declare const selectorEvents: { @@ -8881,123 +9134,6 @@ declare class StorageManager extends Module = ITraitView & T & ThisType; -declare class TraitManager extends Module { - view?: TraitsView; - types: { - [id: string]: { - new (o: any): TraitView; - }; - }; - model: Model; - __ctn?: any; - TraitsView: typeof TraitsView; - events: { - all: string; - custom: string; - }; - /** - * Get configuration object - * @name getConfig - * @function - * @return {Object} - */ - /** - * Initialize module - * @private - */ - constructor(em: EditorModel); - __upSel(): void; - __onUp(): void; - select(component?: Component): void; - getSelected(): Component | undefined; - /** - * Get traits from the currently selected component. - */ - getCurrent(): Trait[]; - __trgCustom(opts?: any): void; - postRender(): void; - /** - * - * Get Traits viewer - * @private - */ - getTraitsViewer(): TraitsView | undefined; - /** - * Add new trait type - * @param {string} name Type name - * @param {Object} methods Object representing the trait - */ - addType(name: string, trait: CustomTrait): void; - /** - * Get trait type - * @param {string} name Type name - * @return {Object} - */ - getType(name: string): new (o: any) => TraitView; - /** - * Get all trait types - * @returns {Object} - */ - getTypes(): { - [id: string]: new (o: any) => TraitView; - }; - render(): HTMLElement; - destroy(): void; -} declare class ItemsView extends View { items: ItemView[]; opt: any; @@ -9071,10 +9207,8 @@ declare class ItemView extends View { clsEdit: string; clsNoEdit: string; _rendered?: boolean; - eyeEl?: JQuery; caret?: JQuery; inputName?: HTMLElement; - cnt?: HTMLElement; constructor(opt: ItemViewProps); initComponent(): void; updateName(): void; @@ -9137,6 +9271,7 @@ declare class ItemView extends View { * @param Event * */ updateStatus(): void; + getItemContainer(): JQuery; /** * Update item aspect after children changes * @@ -9144,7 +9279,7 @@ declare class ItemView extends View { * */ checkChildren(): void; getCaret(): JQuery; - setRoot(el: Component | string): void; + setRoot(cmp: Component | string): void; updateLayerable(): void; __clearItems(): void; remove(...args: [ @@ -10243,13 +10378,15 @@ declare class UtilsModule extends Module { [x: string]: any; }; isComponent: (obj: any) => obj is Component; - getComponentView: (el?: Node | undefined) => ComponentView | undefined; + getComponentView: (el?: Node | undefined) => ComponentView | undefined; getComponentModel: (el?: Node | undefined) => Component | undefined; buildBase64UrlFromSvg: (svg: string) => string; hasDnd: (em: EditorModel) => boolean; upFirst: (value: string) => string; matches: any; - getModel: (el: any, $?: any) => Component | undefined; + getModel: (el: HTMLElement & { + __cashData?: any; + }, $?: any) => Component | undefined; camelCase: (value: string) => string; getElement: (el: HTMLElement) => any; shallowDiff: (objOrig: ObjectAny, objNew: ObjectAny) => ObjectAny; @@ -11567,7 +11704,10 @@ declare abstract class Module implements private _em; private _config; private _name; + debounced: Debounced[]; + collections: Collection[]; cls: any[]; + state?: Model; events: any; model?: any; view?: any; @@ -11576,7 +11716,6 @@ declare abstract class Module implements get config(): T & { pStylePrefix?: string | undefined; }; - abstract destroy(): void; render(opts?: any): HTMLElement | JQuery | void; postLoad(key: any): void; get name(): string; @@ -11585,6 +11724,8 @@ declare abstract class Module implements }; __logWarn(str: string, opts?: {}): void; postRender?(view: any): void; + destroy(): void; + __destroy(): void; /** * Move the main DOM element of the module. * To execute only post editor render (in postRender) @@ -12141,6 +12282,7 @@ export declare const grapesjs: { }; export { + CategoryProperties as BlockCategoryProperties, grapesjs as default, }; diff --git a/src/trait_manager/index.ts b/src/trait_manager/index.ts index f6c2d8fe2..34de95b24 100644 --- a/src/trait_manager/index.ts +++ b/src/trait_manager/index.ts @@ -20,7 +20,7 @@ import TraitNumberView from './view/TraitNumberView'; import TraitSelectView from './view/TraitSelectView'; import TraitView from './view/TraitView'; import TraitsView from './view/TraitsView'; -import { getItemsByCategory } from '../abstract/ModuleCategory'; +import Category, { getItemsByCategory } from '../abstract/ModuleCategory'; import Trait from './model/Trait'; export default class TraitManager extends Module { @@ -138,7 +138,7 @@ export default class TraitManager extends Module { * Get trait categories from the currently selected component. * @return {Array} */ - getCategories() { + getCategories(): Category[] { const cmp = this.state.get('component'); const categories = cmp?.traits.categories?.models || []; return [...categories]; diff --git a/src/trait_manager/model/Traits.ts b/src/trait_manager/model/Traits.ts index 8271a33d8..b4269cbd0 100644 --- a/src/trait_manager/model/Traits.ts +++ b/src/trait_manager/model/Traits.ts @@ -6,6 +6,7 @@ import EditorModel from '../../editor/model/Editor'; import Trait, { TraitProperties } from './Trait'; import TraitFactory from './TraitFactory'; import Categories from '../../abstract/ModuleCategories'; +import TraitManager from '..'; export default class Traits extends CollectionWithCategories { em: EditorModel; @@ -23,7 +24,7 @@ export default class Traits extends CollectionWithCategories { this.tf = new TraitFactory(tmOpts); } - get module() { + get module(): TraitManager { return this.em.Traits; }