Browse Source

Move TraitView to TS

ts-style-manager
Artur Arseniev 4 years ago
parent
commit
13d12288be
  1. 6
      src/trait_manager/model/Trait.ts
  2. 68
      src/trait_manager/view/TraitView.ts
  3. 2
      src/utils/mixins.ts

6
src/trait_manager/model/Trait.ts

@ -2,6 +2,7 @@ import { isUndefined } from 'underscore';
import { Model, SetOptions } from '../../common'; import { Model, SetOptions } from '../../common';
import Component from '../../dom_components/model/Component'; import Component from '../../dom_components/model/Component';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import TraitView from '../view/TraitView';
/** @private */ /** @private */
export interface TraitProperties { export interface TraitProperties {
@ -26,13 +27,14 @@ export interface TraitProperties {
/** /**
* The trait label to show for the rendered trait. * The trait label to show for the rendered trait.
*/ */
label?: string; label?: string | false;
/** /**
* If `true` the trait value is applied on component * If `true` the trait value is applied on component
*/ */
changeProp?: boolean; changeProp?: boolean;
attributes?: Record<string, any>;
min?: number; min?: number;
max?: number; max?: number;
unit?: string; unit?: string;
@ -56,6 +58,8 @@ export interface TraitProperties {
export default class Trait extends Model<TraitProperties> { export default class Trait extends Model<TraitProperties> {
target!: Component; target!: Component;
em?: EditorModel; em?: EditorModel;
view?: TraitView;
el?: HTMLElement;
defaults() { defaults() {
return { return {

68
src/trait_manager/view/TraitView.js → src/trait_manager/view/TraitView.ts

@ -1,30 +1,49 @@
import Backbone from 'backbone'; import Backbone from 'backbone';
import { isUndefined, isString, isFunction } from 'underscore'; import { isUndefined, isString, isFunction } from 'underscore';
import { capitalize } from 'utils/mixins'; import { SetOptions, View } from '../../common';
import { capitalize } from '../../utils/mixins';
import Trait from '../model/Trait';
import EditorModel from '../../editor/model/Editor';
import Component from '../../dom_components/model/Component';
const $ = Backbone.$; const $ = Backbone.$;
export default class TraitView extends Backbone.View { export default class TraitView extends View<Trait> {
events = {}; 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 = true; appendInput = true;
// @ts-ignore
attributes() { attributes() {
return this.model.get('attributes'); return this.model.get('attributes') || {};
} }
templateLabel() { templateLabel(cmp?: Component) {
const { ppfx } = this; const { ppfx } = this;
const label = this.getLabel(); const label = this.getLabel();
return `<div class="${ppfx}label" title="${label}">${label}</div>`; return `<div class="${ppfx}label" title="${label}">${label}</div>`;
} }
templateInput() { templateInput(data: ReturnType<TraitView['getClbOpts']>) {
const { clsField } = this; const { clsField } = this;
return `<div class="${clsField}" data-input></div>`; return `<div class="${clsField}" data-input></div>`;
} }
constructor(o = {}) { constructor(o: any = {}) {
super(o); super(o);
const { config = {} } = o; const { config = {} } = o;
const { model, eventCapture } = this; const { model, eventCapture } = this;
@ -37,10 +56,11 @@ export default class TraitView extends Backbone.View {
this.target = target; this.target = target;
const { ppfx } = this; const { ppfx } = this;
this.clsField = `${ppfx}field ${ppfx}field-${type}`; this.clsField = `${ppfx}field ${ppfx}field-${type}`;
[ const evToListen: [string, any][] = [
['change:value', this.onValueChange], ['change:value', this.onValueChange],
['remove', this.removeView], ['remove', this.removeView],
].forEach(([event, clb]) => { ];
evToListen.forEach(([event, clb]) => {
model.off(event, clb); model.off(event, clb);
this.listenTo(model, event, clb); this.listenTo(model, event, clb);
}); });
@ -68,15 +88,15 @@ export default class TraitView extends Backbone.View {
init() {} init() {}
removed() {} removed() {}
onRender() {} onRender(props: ReturnType<TraitView['getClbOpts']>) {}
onUpdate() {} onUpdate(props: ReturnType<TraitView['getClbOpts']>) {}
onEvent() {} onEvent(props: ReturnType<TraitView['getClbOpts']> & { event: Event }) {}
/** /**
* Fires when the input is changed * Fires when the input is changed
* @private * @private
*/ */
onChange(event) { onChange(event: Event) {
const el = this.getInputElem(); const el = this.getInputElem();
if (el && !isUndefined(el.value)) { if (el && !isUndefined(el.value)) {
this.model.set('value', el.value); this.model.set('value', el.value);
@ -91,7 +111,7 @@ export default class TraitView extends Backbone.View {
return this.model.get('value'); return this.model.get('value');
} }
setInputValue(value) { setInputValue(value: string) {
const el = this.getInputElem(); const el = this.getInputElem();
el && (el.value = value); el && (el.value = value);
} }
@ -100,7 +120,7 @@ export default class TraitView extends Backbone.View {
* On change callback * On change callback
* @private * @private
*/ */
onValueChange(model, value, opts = {}) { onValueChange(model: Trait, value: string, opts: SetOptions & { fromTarget?: boolean } = {}) {
if (opts.fromTarget) { if (opts.fromTarget) {
this.setInputValue(model.get('value')); this.setInputValue(model.get('value'));
this.postUpdate(); this.postUpdate();
@ -117,7 +137,7 @@ export default class TraitView extends Backbone.View {
renderLabel() { renderLabel() {
const { $el, target } = this; const { $el, target } = this;
const label = this.getLabel(); const label = this.getLabel();
let tpl = this.templateLabel(target); let tpl: string | HTMLElement = this.templateLabel(target);
if (this.createLabel) { if (this.createLabel) {
tpl = tpl =
@ -164,7 +184,7 @@ export default class TraitView extends Backbone.View {
const min = md.get('min'); const min = md.get('min');
const max = md.get('max'); const max = md.get('max');
const value = this.getModelValue(); const value = this.getModelValue();
const input = $(`<input type="${type}">`); const input: JQuery<HTMLInputElement> = $(`<input type="${type}">`);
const i18nAttr = em.t(`traitManager.traits.attributes.${name}`) || {}; const i18nAttr = em.t(`traitManager.traits.attributes.${name}`) || {};
input.attr({ input.attr({
placeholder, placeholder,
@ -198,7 +218,7 @@ export default class TraitView extends Backbone.View {
let value; let value;
const model = this.model; const model = this.model;
const target = this.target; const target = this.target;
const name = model.get('name'); const name = model.getName();
if (model.get('changeProp')) { if (model.get('changeProp')) {
value = target.get(name); value = target.get(name);
@ -222,7 +242,7 @@ export default class TraitView extends Backbone.View {
const { $el, appendInput, model } = this; const { $el, appendInput, model } = this;
const inputs = $el.find('[data-input]'); const inputs = $el.find('[data-input]');
const el = inputs[inputs.length - 1]; const el = inputs[inputs.length - 1];
let tpl = model.el; let tpl: HTMLElement | string | undefined = model.el;
if (!tpl) { if (!tpl) {
tpl = this.createInput ? this.createInput(this.getClbOpts()) : this.getInputEl(); tpl = this.createInput ? this.createInput(this.getClbOpts()) : this.getInputEl();
@ -230,10 +250,10 @@ export default class TraitView extends Backbone.View {
if (isString(tpl)) { if (isString(tpl)) {
el.innerHTML = tpl; el.innerHTML = tpl;
this.elInput = el.firstChild; this.elInput = el.firstChild as HTMLInputElement;
} else { } else {
appendInput ? el.appendChild(tpl) : el.insertBefore(tpl, el.firstChild); appendInput ? el.appendChild(tpl!) : el.insertBefore(tpl!, el.firstChild);
this.elInput = tpl; this.elInput = tpl as HTMLInputElement;
} }
model.el = this.elInput; model.el = this.elInput;
@ -245,7 +265,7 @@ export default class TraitView extends Backbone.View {
} }
rerender() { rerender() {
this.model.el = null; delete this.model.el;
this.render(); this.render();
} }
@ -258,7 +278,7 @@ export default class TraitView extends Backbone.View {
const { type, id } = model.attributes; const { type, id } = model.attributes;
const hasLabel = this.hasLabel && this.hasLabel(); const hasLabel = this.hasLabel && this.hasLabel();
const cls = `${pfx}trait`; const cls = `${pfx}trait`;
this.$input = null; delete this.$input;
let tmpl = `<div class="${cls} ${cls}--${type}"> let tmpl = `<div class="${cls} ${cls}--${type}">
${hasLabel ? `<div class="${ppfx}label-wrp" data-label></div>` : ''} ${hasLabel ? `<div class="${ppfx}label-wrp" data-label></div>` : ''}
<div class="${ppfx}field-wrp ${ppfx}field-wrp--${type}" data-input> <div class="${ppfx}field-wrp ${ppfx}field-wrp--${type}" data-input>

2
src/utils/mixins.ts

@ -275,7 +275,7 @@ const isEnterKey = (ev: KeyboardEvent) => getKeyCode(ev) === 13;
const isObject = (val: any): val is Object => val !== null && !Array.isArray(val) && typeof val === 'object'; const isObject = (val: any): val is Object => val !== null && !Array.isArray(val) && typeof val === 'object';
const isEmptyObj = (val: Record<string, any>) => Object.keys(val).length <= 0; const isEmptyObj = (val: Record<string, any>) => Object.keys(val).length <= 0;
const capitalize = (str: string) => str && str.charAt(0).toUpperCase() + str.substring(1); const capitalize = (str: string = '') => str && str.charAt(0).toUpperCase() + str.substring(1);
const isComponent = (obj: any) => obj && obj.toHTML; const isComponent = (obj: any) => obj && obj.toHTML;
const isRule = (obj: any) => obj && obj.toCSS; const isRule = (obj: any) => obj && obj.toCSS;

Loading…
Cancel
Save