grapesjs
Version:
Free and Open Source Web Builder Framework
1,673 lines (1,672 loc) • 469 kB
TypeScript
import Backbone from 'backbone';
import { ModelDestroyOptions, _StringKey } from 'backbone';
declare class ModuleModel<TModule extends IBaseModule<any> = Module, T extends ObjectHash = any, S = SetOptions, E = any> extends Model<T, S, E> {
private _module;
constructor(module: TModule, attributes?: T, options?: CombinedModelConstructorOptions<E>);
get module(): TModule;
get config(): TModule extends IBaseModule<infer C> ? C : unknown;
get em(): EditorModel;
}
export type ModuleExt<TModel extends ModuleModel> = TModel extends ModuleModel<infer M> ? M : unknown;
export type ModelConstructor<TModel extends ModuleModel> = {
new (mod: ModuleExt<TModel>, attr: any): TModel;
};
declare class ModuleCollection<TModel extends ModuleModel = ModuleModel> extends Collection<TModel> {
module: ModuleExt<TModel>;
private newModel;
add(model: Array<Record<string, any>> | TModel, options?: AddOptions): TModel;
add(models: Array<Array<Record<string, any>> | TModel>, options?: AddOptions): TModel[];
constructor(module: ModuleExt<TModel>, models: TModel[] | Array<Record<string, any>>, modelConstructor: ModelConstructor<TModel>);
preinitialize(models?: TModel[] | Array<Record<string, any>>, options?: any): void;
}
export type ModuleFromModel<TModel extends ModuleModel> = TModel extends ModuleModel<infer M> ? M : unknown;
export type ModuleModelExt<TItem extends ModuleModel | ModuleCollection> = TItem extends ModuleCollection<infer M> ? ModuleFromModel<M> : TItem extends ModuleModel<infer M> ? M : unknown;
declare class ModuleView<TModel extends ModuleModel | ModuleCollection = ModuleModel, TElement extends Element = HTMLElement> extends View<TModel extends ModuleModel ? TModel : undefined, TElement> {
protected get pfx(): string;
protected get ppfx(): string;
collection: TModel extends ModuleModel ? ModuleCollection<ModuleModel> : TModel;
protected get module(): ModuleModelExt<TModel>;
protected get em(): EditorModel;
protected get config(): ModuleModelExt<TModel> extends IBaseModule<infer C> ? C : unknown;
className: string;
preinitialize(options?: any): void;
}
export interface DataWatchersOptions {
skipWatcherUpdates?: boolean;
fromDataSource?: boolean;
}
export interface ModelResolverWatcherOptions {
em: EditorModel;
}
export type WatchableModel<T extends ObjectHash> = StyleableModel<T> | undefined;
export interface CategoryViewConfig {
em: EditorModel;
pStylePrefix?: string;
stylePrefix?: string;
}
declare class CategoryView extends View<Category> {
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<string, any>;
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 {
/**
* Category id.
*/
id: string;
/**
* Category label.
*/
label: string;
/**
* Category open state.
* @default true
*/
open?: boolean;
/**
* Category order.
*/
order?: string | number;
/**
* Category attributes.
* @default {}
*/
attributes?: Record<string, any>;
}
export interface ItemsByCategory<T> {
category?: Category;
items: T[];
}
export declare class Category extends Model<CategoryProperties> {
view?: CategoryView;
defaults(): {
id: string;
label: string;
open: boolean;
attributes: {};
};
getId(): string;
getLabel(): string;
}
export interface TraitManagerConfig {
/**
* Style prefix.
* @default 'trt-'
*/
stylePrefix?: string;
/**
* Specify the element to use as a container, string (query) or HTMLElement.
* With the empty value, nothing will be rendered.
* @default ''
*/
appendTo?: string | HTMLElement;
/**
* Avoid rendering the default Trait Manager UI.
* More about it here: [Custom Trait Manager](https://grapesjs.com/docs/modules/Traits.html#custom-trait-manager).
* @default false
*/
custom?: boolean;
optionsTarget?: Record<string, any>[];
}
declare class TraitView extends View<Trait> {
pfx: string;
ppfx: string;
config: any;
clsField: string;
elInput: HTMLInputElement;
input?: HTMLInputElement;
$input?: JQuery<HTMLInputElement>;
eventCapture: string[];
noLabel?: boolean;
em: EditorModel;
target: Component;
createLabel?: (data: {
label: string;
component: Component;
trait: TraitView;
}) => string | HTMLElement;
createInput?: (data: ReturnType<TraitView["getClbOpts"]>) => string | HTMLElement;
events: any;
appendInput: boolean;
/** @ts-ignore */
attributes(): Record<string, any>;
templateLabel(cmp?: Component): string;
templateInput(data: ReturnType<TraitView["getClbOpts"]>): string;
constructor(o?: any);
getClbOpts(): {
component: Component;
trait: Trait;
elInput: HTMLInputElement;
};
removeView(): void;
init(): void;
removed(): void;
onRender(props: ReturnType<TraitView["getClbOpts"]>): void;
onUpdate(props: ReturnType<TraitView["getClbOpts"]>): void;
onEvent(props: ReturnType<TraitView["getClbOpts"]> & {
event: Event;
}): void;
/**
* Fires when the input is changed
* @private
*/
onChange(event: Event): void;
getValueForTarget(): any;
setInputValue(value: string): void;
/**
* On change callback
* @private
*/
onValueChange(_m: Trait, _v: string, opts?: SetOptions & {
fromTarget?: boolean;
}): void;
/**
* Render label
* @private
*/
renderLabel(): void;
/**
* Returns label for the input
* @return {string}
* @private
*/
getLabel(): any;
/**
* Returns current target component
*/
getComponent(): Component;
/**
* Returns input element
* @return {HTMLElement}
* @private
*/
getInputEl(): HTMLInputElement | undefined;
getInputElem(): HTMLInputElement;
getModelValue(): any;
getElInput(): HTMLInputElement;
/**
* Renders input
* @private
* */
renderField(): void;
hasLabel(): boolean;
rerender(): void;
postUpdate(): void;
render(): this;
}
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);
/**
* Add new model to the collection
* @param {Model} model
* @private
* */
addTo(model: any): void;
itemViewNotFound(type: string): void;
/**
* 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<string, CategoryView>;
config: TraitManagerConfigModule;
traitContClass: string;
catsClass: string;
classNoCat: string;
catsEl?: HTMLElement;
traitsEl?: HTMLElement;
rendered?: boolean;
itemsView: TraitManager["types"];
collection: Traits;
constructor(props: TraitsViewProps, itemsView: TraitManager["types"]);
/**
* Update view collection
* @private
*/
updatedCollection(): 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<TraitManagerConfigModule> {
__ctn?: HTMLElement;
view?: TraitsView;
TraitsView: typeof TraitsView;
events: typeof TraitsEvents;
state: Model<TraitModuleStateProps, SetOptions, any>;
types: TraitViewTypes;
/**
* Get configuration object
* @name getConfig
* @function
* @returns {Object}
*/
/**
* Initialize module
* @private
*/
constructor(em: EditorModel);
/**
* Select traits from a component.
* @param {[Component]} component
* @example
* tm.select(someComponent);
*/
select(component?: Component): void;
/**
* Get trait categories from the currently selected component.
* @returns {Array<Category>}
* @example
* const traitCategories: Category[] = tm.getCategories();
*
*/
getCategories(): Category[];
/**
* Get traits from the currently selected component.
* @returns {Array<[Trait]>}
* @example
* const currentTraits: Trait[] = tm.getTraits();
*/
getTraits(): Trait[];
/**
* Get traits by category from the currently selected component.
* @example
* tm.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.
*
* // You can also get the same output format by passing your own array of Traits
* const myFilteredTraits: Trait[] = [...];
* tm.getTraitsByCategory(myFilteredTraits);
*/
getTraitsByCategory(traits?: Trait[]): TraitsByCategory[];
/**
* Get component from the currently selected traits.
* @example
* tm.getComponent();
* // Component {}
*/
getComponent(): Component | undefined;
/**
* Add new trait type.
* More about it here: [Define new Trait type](https://grapesjs.com/docs/modules/Traits.html#define-new-trait-type).
* @param {string} name Type name.
* @param {Object} methods Object representing the trait.
*/
addType<T>(name: string, methods: CustomTrait<T>): void;
/**
* Get trait type
* @param {string} name Type name
* @returns {Object}
* @private
* const traitView = tm.getType('text');
*/
getType(name: string): new (o: any) => TraitView;
/**
* Get all trait types
* @returns {Object}
* @private
*/
getTypes(): TraitViewTypes;
/**
*
* Get Traits viewer
* @private
*/
getTraitsViewer(): TraitsView | undefined;
getCurrent(): Trait[];
render(): HTMLElement;
postRender(): void;
__onSelect(): void;
__trgCustom(opts?: TraitCustomData): void;
__customData(): TraitCustomData;
__upSel(): void;
__onUp(): void;
}
export type CategoryCollectionParams = ConstructorParameters<typeof Collection<Category>>;
export interface CategoryOptions {
events?: {
update?: string;
};
em?: EditorModel;
}
export declare class Categories extends Collection<Category> {
constructor(models?: CategoryCollectionParams[0], opts?: CategoryOptions);
/** @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<T extends Model<ModelWithCategoryProps>> extends Collection<T> {
abstract getCategories(): Categories;
initCategory(model: T): Category | undefined;
}
declare class TraitFactory {
config: Partial<TraitManagerConfig>;
constructor(config?: Partial<TraitManagerConfig>);
/**
* Build props object by their name
*/
build(prop: string | TraitProperties, em: EditorModel): Trait;
private buildFromString;
}
export declare class Traits extends CollectionWithCategories<Trait> {
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<string | TraitProperties | Trait>, options?: AddOptions): Trait[];
}
/**
* @property {String} id Trait id, eg. `my-trait-id`.
* @property {String} type Trait type, defines how the trait should be 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} default Default value to use in case the value is not defined on the component.
* @property {String} placeholder Placeholder to show inside the default input (if the UI type allows it).
* @property {String} [category=''] Trait category.
* @property {Boolean} changeProp If `true`, the trait value is applied on the component property, otherwise, on component attributes.
*
* @module docsjs.Trait
*
*/
export declare class Trait extends Model<TraitProperties> {
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;
get component(): Component;
get changeProp(): boolean;
setTarget(component: Component): void;
/**
* Get the trait id.
* @returns {String}
*/
getId(): string | number;
/**
* 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.
* @param {Object} [opts={}] Options.
* @param {Boolean} [opts.useType=false] Get the value based on type (eg. the checkbox will always return a boolean).
* @returns {any}
*/
getValue(opts?: TraitGetValueOptions): 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): string;
/**
* 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;
/**
* Run the trait command (used on the button trait type).
*/
runCommand(): any;
props(): Partial<TraitProperties>;
targetUpdated(): void;
getTargetValue(opts?: TraitGetValueOptions): any;
setTargetValue(value: any, opts?: SetOptions): void;
setValueFromInput(value: any, final?: boolean, opts?: SetOptions): void;
getInitValue(): any;
}
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<T> = ITraitView & T & ThisType<T & TraitView>;
export interface TraitModuleStateProps {
component?: Component;
traits: Trait[];
}
export interface TraitsByCategory extends ItemsByCategory<Trait> {
}
export interface TraitManagerConfigModule extends TraitManagerConfig {
pStylePrefix?: string;
em: EditorModel;
}
export interface TraitCustomData {
container?: HTMLElement;
}
export interface TraitProperties {
/**
* Trait type, defines how the trait should be rendered.
* Possible values: `text` (default), `number`, `select`, `checkbox`, `color`, `button`
*/
type?: 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.
*/
name?: string;
/**
* Trait id, eg. `my-trait-id`.
* If not specified, the `name` will be used as id.
*/
id?: string | number;
/**
* Trait category.
* @default ''
*/
category?: string | CategoryProperties;
/**
* The trait label to show for the rendered trait.
*/
label?: string | false;
/**
* If `true`, the trait value is applied on the component property, otherwise, on component attributes.
* @default false
*/
changeProp?: boolean;
/**
* Instead of relying on component props/attributes, define your own
* logic on how to get the trait value.
*/
getValue?: (props: {
editor: Editor;
trait: Trait;
component: Component;
}) => any;
/**
* In conjunction with the `getValue`, define your own logic for updating the trait value.
*/
setValue?: (props: {
value: any;
editor: Editor;
trait: Trait;
component: Component;
partial: boolean;
options: TraitSetValueOptions;
emitUpdate: () => void;
}) => void;
/**
* Custom true value for checkbox type.
* @default 'true'
*/
valueTrue?: string;
/**
* Custom false value for checkbox type.
* * @default 'false'
*/
valueFalse?: string;
/**
* Minimum number value for number type.
*/
min?: number;
/**
* Maximum number value for number type.
*/
max?: number;
unit?: string;
/**
* Number of steps for number type.
*/
step?: number;
value?: any;
target?: Component;
default?: any;
/**
* Placeholder to show inside the default input (if the UI type allows it).
*/
placeholder?: string;
/**
* Array of options for the select type.
*/
options?: TraitOption[];
/**
* Label text to use for the button type.
*/
text?: string;
labelButton?: string;
/**
* Command to use for the button type.
*/
command?: string | ((editor: Editor, trait: Trait) => any);
full?: boolean;
attributes?: Record<string, any>;
}
export interface TraitSetValueOptions {
partial?: boolean;
[key: string]: unknown;
}
export interface TraitGetValueOptions {
/**
* Get the value based on type.
* With this option enabled, the returned value is normalized based on the
* trait type (eg. the checkbox will always return a boolean).
* @default false
*/
useType?: boolean;
/**
* If false, return the value
* If true and the value is a data resolver, return the data resolver props
* @default false
*/
skipResolve?: boolean;
}
export interface TraitOption {
id: string;
label?: string;
[key: string]: unknown;
}
declare enum TraitsEvents {
/**
* @event `trait:select` New traits selected (eg. by changing a component).
* @example
* editor.on('trait:select', ({ traits, component }) => { ... });
*/
select = "trait:select",
/**
* @event `trait:value` Trait value updated.
* @example
* editor.on('trait:value', ({ trait, component, value }) => { ... });
*/
value = "trait:value",
/**
* @event `trait:category:update` Trait category updated.
* @example
* editor.on('trait:category:update', ({ category, changes }) => { ... });
*/
categoryUpdate = "trait:category:update",
/**
* @event `trait:custom` Event to use in case of [custom Trait Manager UI](https://grapesjs.com/docs/modules/Traits.html#custom-trait-manager).
* @example
* editor.on('trait:custom', ({ container }) => { ... });
*/
custom = "trait:custom",
/**
* @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, ... }) => { ... });
*/
all = "trait"
}
export interface PageManagerConfig extends ModuleConfig {
/**
* Default pages.
*/
pages?: PageProperties[];
/**
* ID of the page to select on editor load.
*/
selected?: string;
}
export interface SelectableOption {
/**
* Select the page.
*/
select?: boolean;
}
export interface AbortOption {
abort?: boolean;
}
declare enum PagesEvents {
/**
* @event `page:add` Added new page. The page is passed as an argument to the callback.
* @example
* editor.on('page:add', (page) => { ... });
*/
add = "page:add",
addBefore = "page:add:before",
/**
* @event `page:remove` Page removed. The page is passed as an argument to the callback.
* @example
* editor.on('page:remove', (page) => { ... });
*/
remove = "page:remove",
removeBefore = "page:remove:before",
/**
* @event `page:select` New page selected. The newly selected page and the previous one, are passed as arguments to the callback.
* @example
* editor.on('page:select', (page, previousPage) => { ... });
*/
select = "page:select",
selectBefore = "page:select:before",
/**
* @event `page:update` Page updated. The updated page and the object containing changes are passed as arguments to the callback.
* @example
* editor.on('page:update', (page, changes) => { ... });
*/
update = "page:update",
/**
* @event `page` Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback.
* @example
* editor.on('page', ({ event, model, ... }) => { ... });
*/
all = "page"
}
export declare class Frames extends ModuleCollection<Frame> {
loadedItems: number;
itemsToLoad: number;
page?: Page;
constructor(module: CanvasModule, models?: Frame[] | Array<Record<string, any>>);
onAdd(frame: Frame): void;
onReset(m: Frame, opts?: {
previousModels?: Frame[];
}): void;
onRemove(frame: Frame): void;
initRefs(): void;
itemLoaded(): void;
listenToLoad(): void;
listenToLoadItems(on: boolean): void;
}
export interface DataSourceOptions extends CombinedModelConstructorOptions<{
em: EditorModel;
}, DataSource> {
}
export declare class DataSource<DRProps extends DataRecordProps = DataRecordProps> extends Model<DataSourceType<DRProps>> {
transformers: DataSourceTransformers;
/**
* Returns the default properties for the data source.
* These include an empty array of records and an empty object of transformers.
*
* @returns {Object} The default attributes for the data source.
* @name defaults
*/
defaults(): DataSourceType<DRProps>;
/**
* Initializes a new instance of the `DataSource` class.
* It sets up the transformers and initializes the collection of records.
* If the `records` property is not an instance of `DataRecords`, it will be converted into one.
*
* @param {DataSourceProps<DRProps>} props - Properties to initialize the data source.
* @param {DataSourceOptions} opts - Options to initialize the data source.
* @name constructor
*/
constructor(props: DataSourceProps<DRProps>, opts: DataSourceOptions);
/**
* Retrieves the collection of records associated with this data source.
*
* @returns {DataRecords<DRProps>} The collection of data records.
* @name records
*/
get records(): NonNullable<DataRecords<DRProps>>;
/**
* Retrieves the collection of records associated with this data source.
*
* @returns {DataRecords<DRProps>} The collection of data records.
* @name records
*/
get schema(): DataSourceSchema<DRProps>;
/**
* Retrieves the editor model associated with this data source.
*
* @returns {EditorModel} The editor model.
* @name em
*/
get em(): EditorModel;
/**
* Indicates if the data source has a provider for records.
*/
get hasProvider(): boolean;
/**
* Handles the `add` event for records in the data source.
* This method triggers a change event on the newly added record.
*
* @param {DataRecord<DRProps>} dr - The data record that was added.
* @private
* @name onAdd
*/
onAdd(dr: DataRecord<DRProps>): void;
/**
* Adds a new record to the data source.
*
* @param {DRProps} record - The properties of the record to add.
* @param {AddOptions} [opts] - Options to apply when adding the record.
* @returns {DataRecord} The added data record.
* @name addRecord
*/
addRecord(record: DRProps, opts?: AddOptions): DataRecord<DRProps>;
/**
* Retrieves a record from the data source by its ID.
*
* @param {string | number} id - The ID of the record to retrieve.
* @returns {DataRecord<DRProps> | undefined} The data record, or `undefined` if no record is found with the given ID.
* @name getRecord
*/
getRecord(id: string | number): DataRecord | undefined;
/**
* Retrieves all records from the data source.
* Each record is processed with the `getRecord` method to apply any read transformers.
*
* @returns {Array<DataRecord<DRProps> | undefined>} An array of data records.
* @name getRecords
*/
getRecords(): DataRecord<DataRecordProps>[];
/**
* Retrieves all records from the data source with resolved relations based on the schema.
*/
getResolvedRecords(): {
[x: string]: any;
id?: string | undefined;
mutable?: boolean | undefined;
}[];
loadProvider(): Promise<void>;
/**
* Removes a record from the data source by its ID.
*
* @param {string | number} id - The ID of the record to remove.
* @param {RemoveOptions} [opts] - Options to apply when removing the record.
* @returns {DataRecord<DRProps> | undefined} The removed data record, or `undefined` if no record is found with the given ID.
* @name removeRecord
*/
removeRecord(id: string | number, opts?: RemoveOptions): DataRecord<DRProps>;
/**
* Replaces the existing records in the data source with a new set of records.
*
* @param {Array<DRProps>} records - An array of data record properties to set.
* @returns {Array<DataRecord>} An array of the added data records.
* @name setRecords
*/
setRecords(records: DRProps[]): void;
/**
* Update the schema.
* @example
* dataSource.upSchema({ name: { type: 'string' } });
*/
upSchema(schema: Partial<typeof this.schema>, opts?: SetOptions): void;
/**
* Get schema field definition.
* @example
* const fieldSchema = dataSource.getSchemaField('name');
* fieldSchema.type; // 'string'
*/
getSchemaField(fieldKey: keyof DRProps): DataSourceSchema<DRProps>[keyof DRProps];
private handleChanges;
}
export declare class DataRecords<T extends DataRecordProps = DataRecordProps> extends Collection<DataRecord<T>> {
dataSource: DataSource;
constructor(models: DataRecord[] | DataRecordProps[], options: {
dataSource: DataSource;
});
}
export declare class DataRecord<T extends DataRecordProps = DataRecordProps> extends Model<T> {
mutable: boolean;
constructor(props: T, opts?: {});
get cl(): DataRecords;
get dataSource(): DataSource;
get em(): EditorModel;
get index(): number;
/**
* Handles changes to the record's attributes.
* This method triggers a change event for each property that has been altered.
*
* @private
* @name handleChange
*/
handleChange(m: DataRecord, opts: SetOptions): void;
/**
* Get the path of the record.
* The path is a string that represents the location of the record within the data source.
* Optionally, include a property name to create a more specific path.
*
* @param {String} [prop] - Optional property name to include in the path.
* @param {Object} [opts] - Options for path generation.
* @param {Boolean} [opts.useIndex] - Whether to use the index of the record in the path.
* @returns {String} - The path of the record.
* @name getPath
* @example
* const pathRecord = record.getPath();
* // e.g., 'SOURCE_ID.record1'
* const pathRecord2 = record.getPath('myProp');
* // e.g., 'SOURCE_ID.record1.myProp'
*/
getPath(prop?: string, opts?: {
useIndex?: boolean;
}): string;
/**
* Get both ID-based and index-based paths of the record.
* Returns an array containing the paths using both ID and index.
*
* @param {String} [prop] - Optional property name to include in the paths.
* @returns {Array<String>} - An array of paths.
* @name getPaths
* @example
* const paths = record.getPaths();
* // e.g., ['SOURCE_ID.record1', 'SOURCE_ID.0']
*/
getPaths(prop?: string): string[];
/**
* Trigger a change event for the record.
* Optionally, include a property name to trigger a change event for a specific property.
*
* @param {String} [prop] - Optional property name to trigger a change event for a specific property.
* @name triggerChange
*/
triggerChange(prop?: string, options?: SetOptions): void;
/**
* Set a property on the record, optionally using transformers.
* If transformers are defined for the record, they will be applied to the value before setting it.
*
* @param {String|Object} attributeName - The name of the attribute to set, or an object of key-value pairs.
* @param {any} [value] - The value to set for the attribute.
* @param {Object} [options] - Options to apply when setting the attribute.
* @param {Boolean} [options.avoidTransformers] - If true, transformers will not be applied.
* @returns {DataRecord} - The instance of the DataRecord.
* @name set
* @example
* record.set('name', 'newValue');
* // Sets 'name' property to 'newValue'
*/
set<A extends _StringKey<T>>(attributeName: DeepPartialDot<T> | A, value?: SetOptions | T[A] | undefined, options?: SetOptions | undefined): this;
}
declare const DataVariableType: DataComponentTypes.variable;
export interface DataVariableProps {
type?: typeof DataVariableType;
path?: string;
defaultValue?: string;
collectionId?: string;
variableType?: DataCollectionStateType;
asPlainText?: boolean;
}
export interface DataVariableOptions {
em: EditorModel;
collectionsStateMap: DataCollectionStateMap;
}
export declare class DataVariable extends Model<DataVariableProps> {
private em;
private collectionsStateMap;
defaults(): DataVariableProps;
constructor(props: DataVariableProps, options: DataVariableOptions);
get path(): string;
get defaultValue(): string;
get collectionId(): string | undefined;
get variableType(): DataCollectionStateType | undefined;
resolvesFromCollection(): boolean;
updateCollectionsStateMap(collectionsStateMap: DataCollectionStateMap): void;
getResolverPath(): string | false;
toJSON(options?: any): DataVariableProps & {
type: typeof DataVariableType;
};
getDataValue(): any;
static resolveDataSourceVariable(props: {
path?: string;
defaultValue?: string;
}, opts: {
em: EditorModel;
}): any;
static resolveDataResolver(props: {
path?: string;
defaultValue?: string;
collectionId?: string;
variableType?: DataCollectionStateType;
}, opts: DataVariableOptions): any;
private resolveCollectionVariable;
static resolveCollectionVariable(params: {
collectionId?: string;
variableType?: DataCollectionStateType;
path?: string;
defaultValue?: string;
}, ctx: DataVariableOptions): any;
private static resolveCurrentItem;
}
declare enum AnyTypeOperation {
equals = "equals",
isTruthy = "isTruthy",
isFalsy = "isFalsy",
isDefined = "isDefined",
isNull = "isNull",
isUndefined = "isUndefined",
isArray = "isArray",
isObject = "isObject",
isString = "isString",
isNumber = "isNumber",
isBoolean = "isBoolean",
isDefaultValue = "isDefaultValue"
}
declare enum BooleanOperation {
and = "and",
or = "or",
xor = "xor"
}
declare enum NumberOperation {
greaterThan = ">",
lessThan = "<",
greaterThanOrEqual = ">=",
lessThanOrEqual = "<=",
equals = "=",
notEquals = "!="
}
declare enum StringOperation {
contains = "contains",
startsWith = "startsWith",
endsWith = "endsWith",
matchesRegex = "matchesRegex",
equalsIgnoreCase = "equalsIgnoreCase",
trimEquals = "trimEquals"
}
export type DataConditionSimpleOperation = AnyTypeOperation | StringOperation | NumberOperation | BooleanOperation;
export type ConditionProps = ExpressionProps | LogicGroupProps | boolean;
declare const DataConditionType: "data-condition";
export interface ExpressionProps {
left?: any;
operator?: DataConditionSimpleOperation;
right?: any;
}
export interface LogicGroupProps {
logicalOperator: BooleanOperation;
statements: ConditionProps[];
}
export interface DataConditionProps {
type?: typeof DataConditionType;
condition: ConditionProps;
ifTrue?: any;
ifFalse?: any;
}
export type DataConditionOptions = {
em: EditorModel;
onValueChange?: () => void;
collectionsStateMap?: DataCollectionStateMap;
};
export declare class DataCondition extends Model<DataConditionProps> {
private em;
private collectionsStateMap;
private resolverListeners;
private _previousEvaluationResult;
private _conditionEvaluator;
defaults(): {
type: "data-condition";
condition: {
left: string;
operator: StringOperation;
right: string;
};
ifTrue: {};
ifFalse: {};
};
constructor(props: DataConditionProps, opts: DataConditionOptions);
getCondition(): ConditionProps;
getIfTrue(): any;
getIfFalse(): any;
getOperations(): DataConditionSimpleOperation[];
setCondition(condition: ConditionProps): void;
setIfTrue(newIfTrue: any): void;
setIfFalse(newIfFalse: any): void;
isTrue(): boolean;
getDataValue(skipResolve?: boolean): any;
resolvesFromCollection(): boolean;
updateCollectionsStateMap(collectionsStateMap: DataCollectionStateMap): void;
private listenToPropsChange;
private handleConditionChange;
private listenToDataVariables;
private setupConditionDataVariableListeners;
private setupOutputDataVariableListeners;
private setupOutputVariableListener;
private addListener;
private emitConditionEvaluationChange;
private emitOutputValueChange;
private cleanupListeners;
toJSON(): DataConditionProps;
}
export type DataResolver = DataVariable | DataCondition;
export type DataResolverProps = DataVariableProps | DataConditionProps;
export type ResolverFromProps<T extends DataResolverProps> = T extends DataVariableProps ? DataVariable : T extends DataConditionProps ? DataCondition : never;
declare enum DataComponentTypes {
variable = "data-variable",
condition = "data-condition",
conditionTrue = "data-condition-true-content",
conditionFalse = "data-condition-false-content",
collection = "data-collection",
collectionItem = "data-collection-item"
}
declare enum DataCollectionKeys {
rootData = "__rootData"
}
export interface DataRecordProps extends ObjectAny {
/**
* Record id.
*/
id: string;
/**
* Specifies if the record is mutable. Defaults to `true`.
*/
mutable?: boolean;
[key: string]: any;
}
export interface BaseDataSource {
/**
* DataSource id.
*/
id: string;
/**
* DataSource validation and transformation factories.
*/
transformers?: DataSourceTransformers;
/**
* If true will store the data source in the GrapesJS project.json file.
*/
skipFromStorage?: boolean;
[key: string]: unknown;
}
declare enum DataFieldPrimitiveType {
string = "string",
number = "number",
boolean = "boolean",
date = "date",
json = "json",
relation = "relation"
}
export interface DataFieldSchemaBase<T = unknown> {
default?: T;
description?: string;
label?: string;
[key: string]: unknown;
}
export interface DataFieldSchemaString extends DataFieldSchemaBase<string> {
type: DataFieldPrimitiveType.string;
enum?: string[];
}
export interface DataFieldSchemaNumber extends DataFieldSchemaBase<number> {
type: DataFieldPrimitiveType.number;
}
export interface DataFieldSchemaBoolean extends DataFieldSchemaBase<boolean> {
type: DataFieldPrimitiveType.boolean;
}
export interface DataFieldSchemaDate extends DataFieldSchemaBase<Date> {
type: DataFieldPrimitiveType.date;
}
export interface DataFieldSchemaJSON extends DataFieldSchemaBase<any> {
type: DataFieldPrimitiveType.json;
}
export interface DataFieldSchemaRelation extends DataFieldSchemaBase {
type: DataFieldPrimitiveType.relation;
/**
* The target data source ID
*/
target: string;
/**
* The target field in the data source
*/
targetField?: string;
/**
* If true, the relation is one-to-many
*/
isMany?: boolean;
}
export type DataFieldSchemas = DataFieldSchemaString | DataFieldSchemaNumber | DataFieldSchemaBoolean | DataFieldSchemaDate | DataFieldSchemaJSON | DataFieldSchemaRelation;
export type DataSourceSchema<DR extends DataRecordProps = DataRecordProps> = {
[K in keyof DR]?: DataFieldSchemas;
};
export interface DataSourceProviderMethodProps {
url: string;
method?: string;
headers?: HeadersInit;
body?: BodyInit;
}
export interface DataSourceProviderDefinitionProps {
get: string | DataSourceProviderMethodProps;
}
export interface DataSourceProviderResult {
records?: DataRecordProps[];
schema?: DataSourceSchema;
}
export type DataSourceProviderProp = string | DataSourceProviderDefinitionProps;
export interface DataSourceType<DR extends DataRecordProps> extends BaseDataSource {
records: DataRecords<DR>;
schema: DataSourceSchema<DR>;
provider?: DataSourceProviderProp;
}
export interface DataSourceProps<DR extends DataRecordProps = DataRecordProps> extends BaseDataSource {
records?: DataRecords<DR> | DataRecord<DR>[] | DR[];
schema?: DataSourceSchema<DR>;
provider?: DataSourceProviderProp;
}
export interface DataSourceTransformers {
onRecordSetValue?: (args: {
id: string | number;
key: string;
value: any;
}) => any;
}
export type DotSeparatedKeys<T> = T extends object ? {
[K in keyof T]: K extends string ? T[K] extends object ? `${K}` | `${K}.${DotSeparatedKeys<T[K]>}` : `${K}` : never;
}[keyof T] : never;
export type DeepPartialDot<T> = {
[P in DotSeparatedKeys<T>]?: P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Rest extends DotSeparatedKeys<T[K]> ? DeepPartialDot<T[K]>[Rest] : never : never : P extends keyof T ? T[P] : never;
};
export type DataSourceEvent = `${DataSourcesEvents}`;
declare enum DataSourcesEvents {
/**
* @event `data:add` Added new data source.
* @example
* editor.on('data:add', (dataSource) => { ... });
*/
add = "data:add",
addBefore = "data:add:before",
/**
* @event `data:remove` Data source removed.
* @example
* editor.on('data:remove', (dataSource) => { ... });
*/
remove = "data:remove",
removeBefore = "data:remove:before",
/**
* @event `data:update` Data source updated.
* @example
* editor.on('data:update', (dataSource, changes) => { ... });
*/
update = "data:update",
/**
* @event `data:path` Data record path update.
* @example
* editor.on('data:path:SOURCE_ID.RECORD_ID.PROP_NAME', ({ dataSource, dataRecord, path }) => { ... });
* editor.on('data:path', ({ dataSource, dataRecord, path }) => {
* console.log('Path update in any data source')
* });
*/
path = "data:path",
/**
* @event `data:pathSource` Data record path update per source.
* @example
* editor.on('data:pathSource:SOURCE_ID', ({ dataSource, dataRecord, path }) => { ... });
*/
pathSource = "data:pathSource:",
/**
* @event `data:provider:load` Data source provider load.
* @example
* editor.on('data:provider:load', ({ dataSource, result }) => { ... });
*/
providerLoad = "data:provider:load",
providerLoadBefore = "data:provider:load:before",
providerLoadError = "data:provider:load:error",
/**
* @event `data:provider:loadAll` Load of all data source providers (eg. on project load).
* @example
* editor.on('data:provider:loadAll', () => { ... });
*/
providerLoadAll = "data:provider:loadAll",
providerLoadAllBefore = "data:provider:loadAll:before",
/**
* @event `data` Catch-all event for all the events mentioned above.
* @example
* editor.on('data', ({ event, model, ... }) => { ... });
*/
all = "data"
}
/**{END_EVENTS}*/
export interface DataSourcesEventCallback {
[DataSourcesEvents.add]: [
DataSource,
AddOptions
];
[DataSourcesEvents.remove]: [
DataSource,
RemoveOptions
];
[DataSourcesEvents.update]: [
DataSource,
AddOptions
];
[DataSourcesEvents.path]: [
{
dataSource: DataSource;
dataRecord: DataRecord;
path: string;
options: SetOptions;
}
];
[DataSourcesEvents.pathSource]: [
{
dataSource: DataSource;
dataRecord: DataRecord;
path: string;
options: SetOptions;
}
];
[DataSourcesEvents.providerLoad]: [
{
dataSource: DataSource;
result: DataSourceProviderResult;
}
];
[DataSourcesEvents.providerLoadBefore]: [
{
dataSource: DataSource;
}
];
[DataSourcesEvents.providerLoadError]: [
{
dataSource: DataSource;
error: Error;
}
];
[DataSourcesEvents.providerLoadAll]: [
];
[DataSourcesEvents.providerLoadAllBefore]: [
];
[DataSourcesEvents.all]: [
{
event: DataSourceEvent;
model?: Model;
options: ObjectAny;
}
];
}
declare const keyCollectionDefinition = "dataResolver";
export type DataCollectionDataSource = DataVariableProps;
declare enum DataCollectionStateType {
currentIndex = "currentIndex",
startIndex = "startIndex",
currentItem = "currentItem",
currentKey = "currentKey",
endIndex = "endIndex",
collectionId = "collectionId",
totalItems = "totalItems",
remainingItems = "remainingItems"
}
export interface DataCollectionState {
[DataCollectionStateType.currentIndex]: number;
[DataCollectionStateType.startIndex]: number;
[DataCollectionStateType.currentItem]: DataVariableProps;
[DataCollectionStateType.currentKey]: string | number;
[DataCollectionStateType.endIndex]: number;
[DataCollectionStateType.collectionId]: string;
[DataCollectionStateType.totalItems]: number;
[DataCollectionStateType.remainingItems]: number;
}
export type RootDataType = Array<ObjectAny> | ObjectAny;
export interface DataCollectionStateMap {
[key: string]: DataCollectionState | RootDataType | undefined;
rootData?: RootDataType;
}
export interface ComponentDataCollectionProps extends ComponentDefinition {
type: `${DataComponentTypes.collection}`;
[keyCollectionDefinition]: DataCollectionProps;
}
export interface DataCollectionProps {
collectionId: string;
startIndex?: number;
endIndex?: number;
dataSource: DataCollectionDataSource;
}
export interface DataResolverListenerProps {
em: EditorModel;
resolver: DataResolver;
onUpdate: (value: any) => void;
}
declare class DataResolverListener {
private listeners;
private em;
private onUpdate;
private model;
resolver: DataResolver;
constructor(props: DataResolverListenerProps);
private onChange;
private createListener;
listenToResolver(): void;
private listenToConditionalVariable;
private listenToDataVariable;
private removeListeners;
destroy(): void;
}
export interface DomComponentsConfig {
stylePrefix?: string;
/**
* Could be used for default components.
*/
components?: Record<string, any>[];
/**
* If the component is draggable you can drag the component itself (not only from the toolbar).
* @default true
*/
draggableComponents?: boolean;
/**
* Experimental: Disable text inner components.
* With this option, you're able to decide which inner component inside text should be
* disabled (eg. no select, no hover, no layer visibility) once edited.
* @default false
* @example
* // disable all inner childs
* disableTextInnerChilds: true,
* // disable all except link components
* disableTextInnerChilds: (child) => !child.is('link'),
*/
disableTextInnerChilds?: boolean | ((cmp: Component) => boolean | void);
/**
* You can setup a custom component definition processor before adding it into the editor.
* It might be useful to transform custom objects (es. some framework specific JSX) to GrapesJS component one.
* This custom function will be executed on ANY new added component to the editor so make smart checks/conditions
* to avoid doing useless executions
* By default, GrapesJS supports already elements generated from React JSX preset
* @example
* processor: (obj) => {
* if (obj.$$typeof) { // eg. this is a React Element
* const gjsComponent = {
* type: obj.type,
* components: obj.props.children,
* ...
* };
* ...
* return gjsComponent;
* }
* }
*/
processor?: (obj: any) => Record<string, any> | undefined;
/**
* List of HTML void elements.
* https://www.w3.org/TR/2011/WD-html-markup-20110113/syntax.html#void-elements
*/
voidElements?: string[];
/**
* Experimental: Use the frame document for DOM element creation.
* This option might be useful when elements require the local document context to
* work properly (eg. Web Components).
*/
useFrameDoc?: boolean;
}
export declare class Blocks extends CollectionWithCategories<Block> {
em: EditorModel;
constructor(coll: any[], options: {
em: EditorModel;
});
getCategories(): Categories;
handleAdd(model: Block): void;
}
/** @private */
export interface BlockProperties extends DraggableContent {
/**
* Block label, eg. `My block`
*/
label: string;
/**
* HTML string for the media/icon of the block, eg. `<svg ...`, `<img ...`, etc.
* @default ''
*/
media?: string;
/**
* Block category, eg. `Basic blocks`
* @default ''
*/
category?: string | CategoryProperties;
/**
* If true, triggers the `active` event on the dropped component.
* @default false
*/
activate?: boolean;
/**
* If true, the dropped component will be selected.
* @default false
*/
select?: boolean;
/**
* If true, all IDs of dropped components and their styles will be changed.
* @default false
*/
resetId?: boolean;
/**
* Disable the block from being interacted.
* @default false
*/
disable?: boolean;
/**
* Custom behavior on click.
* @example
* onClick: (block, editor) => editor.getWrapper().append(block.get('content'))
*/
onClick?: (block: Block, editor: Editor) => void;
/**
* Block attributes
*/
attributes?: Record<string, any>;
id?: string;
/**
* @deprecated
*/
activeOnRender?: boolean;
}
/**
* @property {String} label Block label, eg. `My block`
* @property {String|Object} content The content of the block. Might be an HTML string or a [Component Definition](/modules/Components.html#component-definition)
* @property {String} [media=''] HTML string for the media/icon of the block, eg. `<svg ...`, `<img ...`, etc.
* @property {String} [category=''] Block category, eg. `Basic blocks`
* @property {Boolean} [activate=false] If true, triggers the `active` event on the dropped component.
* @property {Boolean} [select=false] If true, the dropped component will be selected.
* @property {Boolean} [resetId=false] If true, all IDs of dropped components and their styles will be changed.
* @property {Boolean} [disable=false] Disable the block from being interacted
* @property {Function} [onClick] Custom behavior on click, eg. `(block, editor) => editor.getWrapper().append(block.get('content'))`
* @property {Object} [attributes={}] Block attributes to apply in the view element
*
* @module docsjs.Block
*/
export declare class Block extends Model<BlockProperties> {
defaults(): {
label: string;
content: string;
media: string;
category: string;
activate: boolean;
select: undefined;
resetId: boolean;
disable: boolean;
onClick: undefined;
attributes: {};
dragDef: {};
};
get category(): Category | undefined;
get parent(): Blocks;
/**
* Get block id
* @returns {String}
*/
getId(): string;
/**
* Get block label
* @returns {String}
*/
getLabel(): string;
/**
* Get block media
* @returns {String}
*/
getMedia(): string | undefined;
/**
* Get block content
* @returns {Object|String|Array<Object|String>}
*/
getContent(): ContentType | (() => ContentType) | undefined;
/**
* Get block component dragDef
* @returns {ComponentDefinition}
*/
getDragDef(): ComponentDefinition | undefined;
/**
* Get block category label
* @returns {String}
*/
getCategoryLabel(): string;
}
export interface PropsComponentUpdate {
component: Component;
changed: ObjectAny;
options: ObjectAny;
}
declare class Symbols extends Components {
refreshDbn: Debounced;
constructor(...args: ConstructorParameters<typeof Components>);
removeChildren(component: Component, coll?: Components, opts?: any): void;
onAdd(...args: Parameters<Components["onAdd"]>): void;
onUpdate(props: PropsComponentUpdate): void;
onUpdateDeep(props: PropsComponentUpdate): void;
refresh(): void;
__trgEvent(event: string, props: ObjectAny, isInstance?: boolean): void;
}
export interface SymbolInfo {
isSymbol: boolean;
isMain: boolean;
isInstance: boolean;
isRoot: boolean;
main?: Component;
instances: Component[];
relatives: Component[];
}
export interface ParseStringOptions extends AddOptions, OptionAsDocument, WithHTMLParserOptions {
keepIds?: string[];
cloneRules?: boolean;
}
declare enum ComponentsEvents {
/**
* @event `component:add` New component added.
* @example
* editor.on('component:add', (component) => { ... });
*/
add = "component:add",
/**
* @event `component:remove` Component removed.
* @example
* edito