diff --git a/dist/index.d.ts b/dist/index.d.ts index ef2c87ebf7..c857a9928d 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -5147,7 +5147,6 @@ export declare class Component extends StyleableModel { * @private */ initToolbar(): void; - __loadTraits(tr?: Traits | TraitProperties[], opts?: {}): this; /** * Get traits. * @returns {Array} diff --git a/src/common/traits/index.ts b/src/common/traits/index.ts index 22a7c46d14..e2ca5df992 100644 --- a/src/common/traits/index.ts +++ b/src/common/traits/index.ts @@ -1,9 +1,12 @@ +import { isString } from 'underscore'; import { Model } from '..'; import EditorModel from '../../editor/model/Editor'; +import Trait, { TraitProperties } from './model/Trait'; import TraitButtonView, { TraitButtonViewOpts } from './view/TraitButtonView'; import TraitCheckboxView from './view/TraitCheckboxView'; import TraitColorView from './view/TraitColorView'; -import TraitNumberView, { +import { + TraitNumberView, TraitNumberUnitView, TraitNumberUnitViewOpts, TraitNumberViewOpts, @@ -12,57 +15,53 @@ import TraitSelectView, { TraitSelectViewOpts } from './view/TraitSelectView'; import TraitTextView from './view/TraitTextView'; import TraitView, { TraitViewOpts } from './view/TraitView'; -type InputProperties = - | { type?: string; opts: { em: EditorModel; name?: string } } - | { - type: 'text'; - opts: TraitViewOpts; - } - | { - type: 'number'; - opts: TraitNumberViewOpts | TraitNumberUnitViewOpts; - } - | { - type: 'select'; - opts: TraitSelectViewOpts; - } - | { - type: 'checkbox'; - opts: TraitViewOpts; - } - | { - type: 'color'; - opts: TraitViewOpts; - } - | { - type: 'button'; - opts: TraitButtonViewOpts; - }; - +export type InputViewProperties = + | ({ type?: '' } & TraitViewOpts) + | ({ type: 'text' } & TraitViewOpts) + | ({ type: 'number' } & (TraitNumberViewOpts | TraitNumberUnitViewOpts)) + | ({ type: 'select' } & TraitSelectViewOpts) + | ({ type: 'checkbox' } & TraitViewOpts) + | ({ type: 'color' } & TraitViewOpts) + | ({ type: 'button' } & TraitButtonViewOpts); +export type InputProperties = TraitProperties & { name: string }; export default abstract class InputFactory { + static build(model: Model, trait: string | (InputProperties & InputViewProperties) | Trait): Trait { + if (!(trait instanceof Trait)) { + return isString(trait) ? new Trait(trait, model) : new Trait(trait.name, model, trait); + } else { + return trait; + } + } /** * Build props object by their name */ - static build(name: string, model: M, prop: InputProperties): TraitView { - let type = 'text'; - let opts: any = { name, ...prop.opts }; - if (prop.type !== undefined) { - type = prop.type; - opts = prop.opts; + static buildView( + target: Trait, + em: EditorModel, + opts?: InputViewProperties + ): TraitView { + let type: string | undefined; + let prop: any = { name: target.name, ...opts }; + if (opts !== undefined) { + type = opts.type; + prop = opts; } - - switch (name) { + let view: TraitView; + switch (target.name) { case 'target': - const options = opts.em.Traits.config.optionsTarget; - return new TraitSelectView(name, model, { ...prop.opts, name, default: false, options }); + const options = em.Traits.config.optionsTarget; + view = new TraitSelectView(em, { name: target.name, ...prop, default: false, options }); + break; default: - const ViewClass = this.getView(type, opts); + const ViewClass = this.getView(type, prop); //@ts-ignore - return new ViewClass(name, model, opts); + view = new ViewClass(em, opts); + break; } + return view.setTarget(target); } - private static getView(type: string, opts: any) { + private static getView(type?: string, opts?: any) { switch (type) { case 'text': return TraitTextView; @@ -81,3 +80,11 @@ export default abstract class InputFactory { } } } + +export type { default as TraitButtonView } from './view/TraitButtonView'; +export type { default as TraitCheckboxView } from './view/TraitCheckboxView'; +export type { default as TraitColorView } from './view/TraitColorView'; +export type { TraitNumberView, TraitNumberUnitView } from './view/TraitNumberView'; +export type { default as TraitSelectView } from './view/TraitSelectView'; +export type { default as TraitTextView } from './view/TraitTextView'; +export type { default as TraitView } from './view/TraitView'; diff --git a/src/common/traits/model/Trait.ts b/src/common/traits/model/Trait.ts index 18a7f1b860..537052eb50 100644 --- a/src/common/traits/model/Trait.ts +++ b/src/common/traits/model/Trait.ts @@ -4,17 +4,23 @@ export interface OnUpdateView { onUpdateEvent(value: TraitValueType): void; } -export default class Trait { - private name: string; - private defaultValue: TraitValueType; - private model: Model; +export interface TraitProperties { + default?: any; + value?: any; + changeProp?: boolean; +} + +export default class Trait { + readonly name: string; + opts: TraitProperties; + readonly model: Model; private view?: OnUpdateView; - constructor(name: string, model: Model, defaultValue: TraitValueType) { + constructor(name: string, model: Model, opts?: TraitProperties) { this.name = name; model.on('change:' + name, this.setValueFromModel, this); this.model = model; - this.defaultValue = defaultValue; + this.opts = { ...opts, default: opts?.value ?? opts?.default ?? '' }; } public registerForUpdateEvent(view: OnUpdateView) { @@ -22,13 +28,29 @@ export default class Trait { } public get value(): TraitValueType { - return this.model.get(this.name) ?? this.defaultValue; + const { changeProp, model, name } = this; + const value = changeProp + ? model.get(name) + : // @ts-ignore TODO update post component update + model.getAttributes()[name]; + + return value ?? this.opts.default; + } + public get changeProp(): boolean { + return this.opts.changeProp ?? false; } private updatingValue = false; public set value(value: TraitValueType) { + const { name, model, changeProp } = this; this.updatingValue = true; - this.model.set(this.name, value); + + if (changeProp) { + model.set(name, value); + } else { + //@ts-ignore + model.addAttributes({ [name]: value }); + } this.updatingValue = false; } @@ -37,4 +59,8 @@ export default class Trait { this.view?.onUpdateEvent(this.value); } } + + updateOpts(opts: any) { + this.opts = { ...this.opts, ...opts }; + } } diff --git a/src/common/traits/view/TraitButtonView.ts b/src/common/traits/view/TraitButtonView.ts index e5b711184c..14796790c3 100644 --- a/src/common/traits/view/TraitButtonView.ts +++ b/src/common/traits/view/TraitButtonView.ts @@ -1,6 +1,7 @@ import { isString } from 'underscore'; import { Model, $ } from '../..'; import Editor from '../../../editor'; +import EditorModel from '../../../editor/model/Editor'; import TraitView, { TraitViewOpts } from './TraitView'; export interface TraitButtonViewOpts extends TraitViewOpts { @@ -20,8 +21,8 @@ export default class TraitButtonView extends TraitView) { - super(popertyName, model, opts); + constructor(em: EditorModel, opts: TraitButtonViewOpts) { + super(em, opts); this.command = opts.command; this.text = opts.text; this.full = opts.full; diff --git a/src/common/traits/view/TraitNumberView.ts b/src/common/traits/view/TraitNumberView.ts index d08828957f..10fa9c9828 100644 --- a/src/common/traits/view/TraitNumberView.ts +++ b/src/common/traits/view/TraitNumberView.ts @@ -1,5 +1,6 @@ import { bindAll, indexOf, isUndefined } from 'underscore'; import { Model, $ } from '../..'; +import EditorModel from '../../../editor/model/Editor'; import { off, on } from '../../../utils/dom'; import TraitView, { TraitViewOpts } from './TraitView'; @@ -31,8 +32,8 @@ abstract class TraitNumberViewAbstract ext }; } - constructor(popertyName: string, model: TModel, opts: TraitNumberViewOpts) { - super(popertyName, model, opts); + constructor(em: EditorModel, opts: TraitNumberViewOpts) { + super(em, opts); bindAll(this, 'moveIncrement', 'upIncrement'); this.step = opts.step ?? 1; this.min = opts.min; @@ -245,11 +246,11 @@ abstract class TraitNumberViewAbstract ext } } -export default class TraitNumberView extends TraitNumberViewAbstract { +export class TraitNumberView extends TraitNumberViewAbstract { unitEl?: any; - constructor(popertyName: string, model: TModel, opts: TraitNumberViewOpts) { - super(popertyName, model, opts); + constructor(em: EditorModel, opts: TraitNumberViewOpts) { + super(em, opts); } get inputValue(): number { @@ -269,8 +270,8 @@ export class TraitNumberUnitView extends TraitNumberViewAb unitEl?: HTMLSelectElement; units: string[]; - constructor(popertyName: string, model: TModel, opts: TraitNumberUnitViewOpts) { - super(popertyName, model, opts); + constructor(em: EditorModel, opts: TraitNumberUnitViewOpts) { + super(em, opts); this.units = opts.units; } diff --git a/src/common/traits/view/TraitSelectView.ts b/src/common/traits/view/TraitSelectView.ts index 5941702d12..211f0e4a24 100644 --- a/src/common/traits/view/TraitSelectView.ts +++ b/src/common/traits/view/TraitSelectView.ts @@ -1,5 +1,6 @@ import { isString, isUndefined } from 'underscore'; import { Model, $ } from '../..'; +import EditorModel from '../../../editor/model/Editor'; import TraitView, { TraitViewOpts } from './TraitView'; type SelectOption = @@ -18,8 +19,8 @@ export default class TraitSelectView extends TraitView +export default abstract class TraitView extends View implements OnUpdateView { @@ -32,9 +34,9 @@ export default abstract class TraitView input?: HTMLInputElement; $input?: JQuery; eventCapture!: string[]; - noLabel?: boolean; + noLabel: boolean; em: EditorModel; - target: Trait; + target!: Trait; events(): EventsHash { return { @@ -55,18 +57,29 @@ export default abstract class TraitView return `
`; } - constructor(popertyName: string, model: TModel, opts: TraitViewOpts) { - super({ model }); - this.em = opts.em; + constructor(em: EditorModel, opts?: TraitViewOpts) { + super({}); + this.em = em; const config = this.em.Traits.config; this.ppfx = config.pStylePrefix || ''; this.pfx = this.ppfx + config.stylePrefix || ''; - this.name = opts.name; - this.target = new Trait(popertyName, model, opts.default ?? ''); - this.target.registerForUpdateEvent(this); + this.name = opts?.name; + this.noLabel = opts?.noLabel ?? false; + } + setTarget(popertyName: string, model: TModel, opts?: TraitProperties): this; + setTarget(target: Trait): this; + setTarget(target: unknown, model?: TModel, opts?: TraitProperties) { + if (isString(target) && model !== undefined) { + target = new Trait(target, model, opts); + } + this.target = target as Trait; + this.model = this.target.model as any; + this.name ?? (this.name = this.target.name); this.listenTo(model, 'change:label', this.render); this.listenTo(model, 'change:placeholder', this.rerender); + this.target.registerForUpdateEvent(this); + return this; } abstract get inputValue(): TraitValueType; @@ -146,8 +159,7 @@ export default abstract class TraitView } hasLabel() { - const { label } = this.model.attributes; - return !this.noLabel && label !== false; + return !this.noLabel; } rerender() { @@ -157,7 +169,7 @@ export default abstract class TraitView render() { const { $el, pfx, ppfx, name, type } = this; - const hasLabel = this.hasLabel && this.hasLabel(); + const hasLabel = this.hasLabel(); const cls = `${pfx}trait`; delete this.$input; let tmpl = `
diff --git a/src/common/traits/view/TraitViewList.ts b/src/common/traits/view/TraitViewList.ts new file mode 100644 index 0000000000..b8ca00fa00 --- /dev/null +++ b/src/common/traits/view/TraitViewList.ts @@ -0,0 +1,36 @@ +import { TraitView } from '..'; +import { View } from '../..'; + +export default class TraitViewList extends View { + inputs: TraitView[]; + constructor(inputs?: TraitView[], el?: any) { + super({ el }); + this.inputs = inputs ?? []; + console.log(this.inputs); + } + + add(input: TraitView) { + this.inputs.push(input); + } + + clean() { + this.inputs = []; + } + + render() { + var frag = document.createDocumentFragment(); + this.$el.empty(); + + if (this.inputs.length) { + this.inputs.forEach(view => { + const rendered = view.render().el; + console.log(rendered); + frag.appendChild(rendered); + }); + } + console.log(frag); + + this.$el.append(frag); + return this; + } +} diff --git a/src/dom_components/model/Component.ts b/src/dom_components/model/Component.ts index d5a482c158..280492dff0 100644 --- a/src/dom_components/model/Component.ts +++ b/src/dom_components/model/Component.ts @@ -17,7 +17,6 @@ import { Model } from 'backbone'; import Components from './Components'; import Selector from '../../selector_manager/model/Selector'; import Selectors from '../../selector_manager/model/Selectors'; -import Traits from '../../trait_manager/model/Traits'; import EditorModel from '../../editor/model/Editor'; import { ComponentAdd, @@ -34,8 +33,9 @@ import { DomComponentsConfig } from '../config/config'; import ComponentView from '../view/ComponentView'; import { AddOptions, ExtractMethods, ObjectAny, PrevToNewIdMap, SetOptions } from '../../common'; import CssRule, { CssRuleJSON } from '../../css_composer/model/CssRule'; -import Trait, { TraitProperties } from '../../trait_manager/model/Trait'; import { ToolbarButtonProps } from './ToolbarButton'; +import InputFactory, { InputProperties, InputViewProperties } from '../../common/traits'; +import Trait from '../../common/traits/model/Trait'; export interface IComponent extends ExtractMethods {} @@ -168,8 +168,8 @@ export default class Component extends StyleableModel { return this.get('classes')!; } - get traits() { - return this.get('traits')!; + get traits(): Trait[] { + return this.get('traits')! as any; } get content() { @@ -271,7 +271,7 @@ export default class Component extends StyleableModel { this.views = []; // Register global updates for collection properties - ['classes', 'traits', 'components'].forEach(name => { + ['classes', 'components'].forEach(name => { const events = `add remove ${name !== 'components' ? 'change' : ''}`; this.listenTo(this.get(name), events.trim(), (...args) => this.emitUpdate(name, ...args)); }); @@ -1059,16 +1059,6 @@ export default class Component extends StyleableModel { const event = 'change:traits'; this.off(event, this.initTraits); this.__loadTraits(); - const attrs = { ...this.get('attributes') }; - const traits = this.traits; - traits.each(trait => { - if (!trait.get('changeProp')) { - const name = trait.get('name'); - const value = trait.getInitValue(); - if (name && value) attrs[name] = value; - } - }); - traits.length && this.set('attributes', attrs); this.on(event, this.initTraits); changed && em && em.trigger('component:toggled'); return this; @@ -1252,22 +1242,18 @@ export default class Component extends StyleableModel { } } - __loadTraits(tr?: Traits | TraitProperties[], opts = {}) { - let traitsI = tr || this.traits; - - if (!(traitsI instanceof Traits)) { - traitsI = (isFunction(traitsI) ? traitsI(this) : traitsI) as TraitProperties[]; - const traits = new Traits([], this.opt as any); - traits.setTarget(this); - - if (traitsI.length) { - traitsI.forEach(tr => tr.attributes && delete tr.attributes.value); - traits.add(traitsI); + __loadTraits(tr?: (Trait | (InputViewProperties & InputProperties) | string)[]) { + let traits = tr || this.traits; + this.set('traits', traits.map(trait => InputFactory.build(this as any, trait)) as any); + const attrs = { ...this.get('attributes') }; + this.traits.forEach(trait => { + if (!trait.changeProp) { + const name = trait.name; + const value = trait.value; + if (name && value) attrs[name] = value; } - - this.set({ traits }, opts); - } - + }); + traits.length && this.set('attributes', attrs); return this; } @@ -1280,8 +1266,7 @@ export default class Component extends StyleableModel { * // [Trait, Trait, Trait, ...] */ getTraits(): Trait[] { - this.__loadTraits(); - return [...this.traits.models]; + return this.traits; } /** @@ -1293,10 +1278,9 @@ export default class Component extends StyleableModel { * console.log(traits); * // [Trait, ...] */ - setTraits(traits: TraitProperties[]) { + setTraits(traits: (Trait | (InputViewProperties & InputProperties) | string)[]) { const tr = isArray(traits) ? traits : [traits]; - // @ts-ignore - this.set({ traits: tr }); + this.__loadTraits(tr); return this.getTraits(); } @@ -1309,11 +1293,7 @@ export default class Component extends StyleableModel { * traitTitle && traitTitle.set('label', 'New label'); */ getTrait(id: string) { - return ( - this.getTraits().filter(trait => { - return trait.get('id') === id || trait.get('name') === id; - })[0] || null - ); + return this.getTraits().find(trait => trait.name === id) || null; } /** @@ -1327,9 +1307,9 @@ export default class Component extends StyleableModel { * options: [ 'Option 1', 'Option 2' ], * }); */ - updateTrait(id: string, props: Partial) { + updateTrait(id: string, props: Partial) { const trait = this.getTrait(id); - trait && trait.set(props); + trait?.updateOpts(props); this.em?.trigger('component:toggled'); return this; } @@ -1358,9 +1338,12 @@ export default class Component extends StyleableModel { */ removeTrait(id: string | string[]) { const ids = isArray(id) ? id : [id]; - const toRemove = ids.map(id => this.getTrait(id)); - const { traits } = this; - const removed = toRemove.length ? traits.remove(toRemove) : []; + const removed = ids.map(id => { + const index = this.getTraitIndex(id); + if (index != -1) { + return this.traits.splice(index, 1)[0]; + } + }); this.em?.trigger('component:toggled'); return isArray(removed) ? removed : [removed]; } @@ -1378,11 +1361,15 @@ export default class Component extends StyleableModel { * }); * component.addTrait(['title', {...}, ...]); */ - addTrait(trait: Parameters[0], opts: AddOptions = {}) { - this.__loadTraits(); - const added = this.traits.add(trait, opts); + addTrait(trait: (Trait | (InputViewProperties & InputProperties) | string)[], opts: AddOptions = {}) { + const traits = isArray(trait) ? trait : [trait]; + const added = traits.map(add => { + const tr = InputFactory.build(this as any, add); + this.traits.push(tr); + return tr; + }); this.em?.trigger('component:toggled'); - return isArray(added) ? added : [added]; + return added; } /** @@ -1418,7 +1405,6 @@ export default class Component extends StyleableModel { attr.components = []; // @ts-ignore attr.classes = []; - // @ts-ignore attr.traits = []; if (this.__isSymbolTop()) { @@ -1429,9 +1415,8 @@ export default class Component extends StyleableModel { // @ts-ignore attr.components[i] = md.clone({ ...opt, _inner: 1 }); }); - this.get('traits')!.each((md, i) => { - // @ts-ignore - attr.traits[i] = md.clone(); + this.traits.forEach((md, i) => { + attr.traits![i] = { ...md.opts, name: md.name }; }); this.get('classes')!.each((md, i) => { // @ts-ignore diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts index 26a9822c94..f2c5b12335 100644 --- a/src/dom_components/model/types.ts +++ b/src/dom_components/model/types.ts @@ -1,9 +1,9 @@ import Frame from '../../canvas/model/Frame'; import { Nullable } from '../../common'; +import { InputProperties, InputViewProperties } from '../../common/traits'; import EditorModel from '../../editor/model/Editor'; import Selectors from '../../selector_manager/model/Selectors'; import { TraitProperties } from '../../trait_manager/model/Trait'; -import Traits from '../../trait_manager/model/Traits'; import { ResizerOptions } from '../../utils/Resizer'; import { DomComponentsConfig } from '../config/config'; import Component from './Component'; @@ -189,9 +189,9 @@ export interface ComponentProperties { //script-export?: string | ((...params: any[]) => any); /** * Component's traits. More about it [here](/modules/Traits.html). Default: `['id', 'title']` - * @default '' + * @default [] */ - traits?: Traits; + traits?: (string | (InputProperties & (InputViewProperties | {})))[]; /** * Indicates an array of properties which will be inhereted by all NEW appended children. For example if you create a component likes this: `{ removable: false, draggable: false, propagate: ['removable', 'draggable'] }` diff --git a/src/pages/index.ts b/src/pages/index.ts index fe900d37bf..3a3468dd1d 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -55,7 +55,6 @@ import ComponentWrapper from '../dom_components/model/ComponentWrapper'; import { AddOptions, Model, RemoveOptions, SetOptions, View } from '../common'; import PagesView from './view/PagesView'; import config, { PageManagerConfig } from './config/config'; -import TraitTextView from '../common/traits/view/TraitTextView'; import PageEditView from './view/PageEditView'; interface SelectableOption { diff --git a/src/pages/view/PageEditView.ts b/src/pages/view/PageEditView.ts index 78a4941c4d..45a40a95a1 100644 --- a/src/pages/view/PageEditView.ts +++ b/src/pages/view/PageEditView.ts @@ -2,7 +2,7 @@ import { View } from '../../common'; import TraitButtonView from '../../common/traits/view/TraitButtonView'; import TraitCheckboxView from '../../common/traits/view/TraitCheckboxView'; import TraitColorView from '../../common/traits/view/TraitColorView'; -import TraitNumberView, { TraitNumberUnitView } from '../../common/traits/view/TraitNumberView'; +import { TraitNumberView, TraitNumberUnitView } from '../../common/traits/view/TraitNumberView'; import TraitSelectView from '../../common/traits/view/TraitSelectView'; import TraitTextView from '../../common/traits/view/TraitTextView'; import EditorModel from '../../editor/model/Editor'; @@ -23,29 +23,40 @@ export default class PageEditView extends View { this.$el.empty(); this.$el.attr('class', this.className); if (this.model) { - let input = new TraitNumberView('name', this.model, { em, name: 'name', min: 0 }); + let input = new TraitNumberView(em, { name: 'name', min: 0 }); + input.setTarget('name', this.model, { changeProp: true }); this.$el.append(input.render().el); - let input3 = new TraitNumberUnitView('name', this.model, { em, name: 'name', min: 0, units: ['px', '%'] }); + let input3 = new TraitNumberUnitView(em, { name: 'name', min: 0, units: ['px', '%'] }); + input3.setTarget('name', this.model, { changeProp: true }); this.$el.append(input3.render().el); - this.$el.append(new TraitSelectView('name', this.model, { em, name: 'name', options: ['px', '%'] }).render().el); + this.$el.append( + new TraitSelectView(em, { name: 'name', options: ['px', '%'] }) + .setTarget('name', this.model, { changeProp: true }) + .render().el + ); - this.$el.append(new TraitCheckboxView('name', this.model, { em, name: 'name' }).render().el); + this.$el.append( + new TraitCheckboxView(em, { name: 'name' }).setTarget('name', this.model, { changeProp: true }).render().el + ); this.$el.append( - new TraitButtonView('name', this.model, { - em, + new TraitButtonView(em, { name: 'name', text: 'Ok', command: () => { console.log('click'); }, - }).render().el + }) + .setTarget('name', this.model, { changeProp: true }) + .render().el + ); + this.$el.append( + new TraitColorView(em, { name: 'name' }).setTarget('name', this.model, { changeProp: true }).render().el ); - this.$el.append(new TraitColorView('name', this.model, { em, name: 'name' }).render().el); - let input2 = new TraitTextView('name', this.model, { em, name: 'route' }); + let input2 = new TraitTextView(em, { name: 'route' }).setTarget('name', this.model, { changeProp: true }); this.$el.append(input2.render().el); } return this; @@ -68,7 +79,6 @@ export default class PageEditView extends View { changePage(page: Page) { this.model = page; this.render(); - console.log('changePage'); } public get em(): EditorModel { diff --git a/src/pages/view/PageView.ts b/src/pages/view/PageView.ts index 146f4348fd..d6d4c454e4 100644 --- a/src/pages/view/PageView.ts +++ b/src/pages/view/PageView.ts @@ -18,7 +18,7 @@ export default class PageView extends View { render() { const { em, pfx, ppfx, model } = this; this.$el.attr('class', this.className); - let input = new TraitTextView('name', model, { em }); + let input = new TraitTextView(em).setTarget('name', this.model, { changeProp: true }); this.$el.append(input.render().el); return this; } diff --git a/src/trait_manager/index.ts b/src/trait_manager/index.ts index d96d5388da..b7f557ec4c 100644 --- a/src/trait_manager/index.ts +++ b/src/trait_manager/index.ts @@ -11,7 +11,9 @@ import TraitColorView from './view/TraitColorView'; import TraitButtonView from './view/TraitButtonView'; import EditorModel from '../editor/model/Editor'; import Component from '../dom_components/model/Component'; -import Trait from './model/Trait'; +import Trait from '../common/traits/model/Trait'; +import TraitViewList from '../common/traits/view/TraitViewList'; +import InputFactory from '../common/traits'; export const evAll = 'trait'; export const evPfx = `${evAll}:`; @@ -39,7 +41,7 @@ interface ITraitView { export type CustomTrait = ITraitView & T & ThisType; export default class TraitManager extends Module { - view?: TraitsView; + view?: TraitViewList; types: { [id: string]: { new (o: any): TraitView } }; model: Model; __ctn?: any; @@ -85,8 +87,8 @@ export default class TraitManager extends Module InputFactory.buildView(trait, em, trait.opts as any)); + this.view = new TraitViewList(traitViews, el).render(); + + return this.view.el; } destroy() { diff --git a/test/specs/dom_components/model/Component.ts b/test/specs/dom_components/model/Component.ts index 93235aaa3a..cb8565e66c 100644 --- a/test/specs/dom_components/model/Component.ts +++ b/test/specs/dom_components/model/Component.ts @@ -46,16 +46,16 @@ describe('Component', () => { }); test('Clones correctly with traits', () => { - obj.traits.at(0).set('value', 'testTitle'); + obj.traits[0].value = 'testTitle'; var cloned = obj.clone(); cloned.set('stylable', 0); - cloned.traits.at(0).set('value', 'testTitle2'); - expect(obj.traits.at(0).get('value')).toEqual('testTitle'); + cloned.traits[0].value = 'testTitle2'; + expect(obj.traits[0].value).toEqual('testTitle'); expect(obj.get('stylable')).toEqual(true); }); test('Sets attributes correctly from traits', () => { - obj.set('traits', [ + obj.setTraits([ { label: 'Title', name: 'title', @@ -64,8 +64,8 @@ describe('Component', () => { { label: 'Context', value: 'primary', - }, - ] as any); + } as any, + ]); expect(obj.get('attributes')).toEqual({ title: 'The title' }); });