diff --git a/src/style_manager/model/Property.js b/src/style_manager/model/Property.js index ac85790c7..fb0afbc31 100644 --- a/src/style_manager/model/Property.js +++ b/src/style_manager/model/Property.js @@ -8,6 +8,13 @@ import { capitalize, camelCase, hasWin } from 'utils/mixins'; * @property {String} property Related CSS property name, eg. `text-align`. * @property {String} default Defaul value of the property. * @property {String} label Label to use in UI, eg. `Text Align`. + * @property {Function} [onChange] Change callback. + * \n + * ```js + * onChange: ({ property, from, to }) => { + * console.log(`Changed property`, property.getName(), { from, to }); + * } + * ``` * */ export default class Property extends Model { @@ -44,7 +51,10 @@ export default class Property extends Model { const kProps = [...keys(this.__getClearProps()), '__p']; const toProps = keys(to); const applyStyle = !opts.__up && !parentProp && (isClear || kProps.some(k => toProps.indexOf(k) >= 0)); - sm.__trgEv(sm.events.propertyUpdate, { property: this, from, to, value, opts }); + const onChange = this.get('onChange'); + const evOpts = { property: this, from, to, value, opts }; + sm.__trgEv(sm.events.propertyUpdate, evOpts); + onChange && onChange(evOpts); applyStyle && this.__upTargetsStyle({ [name]: value }, opts); } @@ -60,6 +70,10 @@ export default class Property extends Model { return this.set(props, { ...rest, avoidStore: props.__p }); } + up(props, opts = {}) { + this.set(props, { ...opts, __up: true }); + } + init() {} /** @@ -378,6 +392,16 @@ export default class Property extends Model { return this.__parentTarget || null; } + __parseFn(input = '') { + const start = input.indexOf('(') + 1; + const end = input.lastIndexOf(')'); + + return { + name: input.substring(0, start - 1).trim(), + value: String.prototype.substring.apply(input, [start, end >= 0 ? end : undefined]).trim(), + }; + } + __checkVisibility({ target, component, sectors }) { const trg = component || target; if (!trg) return false; @@ -468,6 +492,7 @@ Property.prototype.defaults = { status: '', visible: true, fixedValues: ['initial', 'inherit'], + onChange: null, // If true, the property will be forced to be full width full: 0, diff --git a/src/style_manager/model/PropertyComposite.js b/src/style_manager/model/PropertyComposite.js index bbc02832e..556c6b268 100644 --- a/src/style_manager/model/PropertyComposite.js +++ b/src/style_manager/model/PropertyComposite.js @@ -16,7 +16,7 @@ export const isNumberType = type => type === 'integer' || type === 'number'; * @property {Function} [fromStyle] Custom logic for getting property values from the target style object. * \n * ```js - * fromStyle(style) => { + * fromStyle: (style) => { * const margins = parseMarginShorthand(style.margin); * return { * 'margin-top': margins.top, @@ -27,7 +27,7 @@ export const isNumberType = type => type === 'integer' || type === 'number'; * @property {Function} [toStyle] Custom logic for creating the CSS style object to apply on selected targets. * \n * ```js - * toStyle(values) => { + * toStyle: (values) => { * const top = values['margin-top'] || 0; * const right = values['margin-right'] || 0; * // ... diff --git a/src/style_manager/model/PropertyStack.js b/src/style_manager/model/PropertyStack.js index e957f362a..e2288c759 100644 --- a/src/style_manager/model/PropertyStack.js +++ b/src/style_manager/model/PropertyStack.js @@ -283,8 +283,9 @@ export default class PropertyStack extends PropertyComposite { __upProperties(prop, opts = {}) { const layer = this.getSelectedLayer(); - if (opts.__up || !layer) return; + if (!layer) return; layer.upValues({ [prop.getId()]: prop.__getFullValue() }); + if (opts.__up) return; this.__upTargetsStyleProps(opts); } @@ -453,10 +454,6 @@ export default class PropertyStack extends PropertyComposite { return style[this.getName()]; } - getFullValue() { - return this.get('detached') ? '' : this.get('layers').getFullValue(); - } - /** * Extended * @private