Browse Source

Change dynamic style events behviour (#6555)

* Emit event on setting a style with dynamic value

* Fix event when binding to a data value equals to the previous static value

* Fix dataResolver listening bug after loading a project
release-v0.22.9
mohamed yahia 7 months ago
committed by GitHub
parent
commit
a087e9404d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      packages/core/src/data_sources/model/DataResolverListener.ts
  2. 2
      packages/core/src/dom_components/model/ModelDataResolverWatchers.ts
  3. 10
      packages/core/src/domain_abstract/model/StyleableModel.ts
  4. 104
      packages/core/test/specs/data_sources/serialization.ts

15
packages/core/src/data_sources/model/DataResolverListener.ts

@ -75,12 +75,11 @@ export default class DataResolverListener {
private listenToDataVariable(dataVariable: DataVariable): ListenerWithCallback[] {
const { em } = this;
const dataListeners: ListenerWithCallback[] = [];
dataListeners.push(
this.createListener(dataVariable, 'change', () => {
this.listenToResolver();
this.onChange();
}),
);
const onChangeAndRewatch = () => {
this.listenToResolver();
this.onChange();
};
dataListeners.push(this.createListener(dataVariable, 'change', onChangeAndRewatch));
const path = dataVariable.getResolverPath();
if (!path) return dataListeners;
@ -89,7 +88,7 @@ export default class DataResolverListener {
const [ds, dr] = em.DataSources.fromPath(path!);
if (ds) {
dataListeners.push(this.createListener(ds.records, 'add remove reset'));
dataListeners.push(this.createListener(ds.records, 'add remove reset', onChangeAndRewatch));
}
if (dr) {
@ -97,7 +96,7 @@ export default class DataResolverListener {
}
dataListeners.push(
this.createListener(em.DataSources.all, 'add remove reset'),
this.createListener(em.DataSources.all, 'add remove reset', onChangeAndRewatch),
this.createListener(em, `${DataSourcesEvents.path}:${normPath}`),
);

2
packages/core/src/dom_components/model/ModelDataResolverWatchers.ts

@ -32,7 +32,7 @@ export class ModelDataResolverWatchers {
}
private onStyleUpdate(component: StyleableModel | undefined, key: string, value: any) {
component?.addStyle({ [key]: value }, { ...updateFromWatcher, noEvent: true, partial: true, avoidStore: true });
component?.addStyle({ [key]: value }, { ...updateFromWatcher, partial: true, avoidStore: true });
}
bindModel(model: StyleableModel) {

10
packages/core/src/domain_abstract/model/StyleableModel.ts

@ -91,7 +91,7 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T,
prop = this.parseStyle(prop);
}
const propOrig = this.getStyle({ skipResolve: true });
const propOrig = this.getStyle('', { skipResolve: true });
if (opts.partial || opts.avoidStore) {
opts.avoidStore = true;
@ -114,7 +114,13 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T,
this.set('style', newStyle, opts as any);
const diff = shallowDiff(propOrig, newStyle);
const changedKeys = Object.keys(shallowDiff(propOrig, propNew));
const diff: ObjectAny = changedKeys.reduce((acc, key) => {
return {
...acc,
[key]: newStyle[key],
};
}, {});
// Delete the property used for partial updates
delete diff.__p;

104
packages/core/test/specs/data_sources/serialization.ts

@ -412,5 +412,109 @@ describe('DataSource Serialization', () => {
},
});
});
test('should resolve styles, props, and attributes if the entire datasource is added after load', () => {
const styleVar = {
type: DataVariableType,
defaultValue: 'black',
path: 'new-unified-data.styleRecord.color',
};
const propAttrVar = {
type: DataVariableType,
defaultValue: 'default-value',
path: 'new-unified-data.propRecord.value',
};
const componentProjectData: ProjectData = {
pages: [
{
frames: [
{
component: {
components: [
{
attributes: { id: 'selectorid', 'data-test': propAttrVar },
tagName: 'div',
customProp: propAttrVar,
},
],
},
},
],
},
],
styles: [{ selectors: ['#selectorid'], style: { color: styleVar } }],
dataSources: [], // Start with no datasources
};
editor.loadProjectData(componentProjectData);
const component = editor.getComponents().at(0); // Assert fallback to defaults before adding the data source
expect(component.getStyle()).toEqual({ color: 'black' });
expect(component.get('customProp')).toBe('default-value');
expect(component.getAttributes()['data-test']).toBe('default-value');
editor.DataSources.add({
id: 'new-unified-data',
records: [
{ id: 'styleRecord', color: 'green' },
{ id: 'propRecord', value: 'resolved-value' },
],
});
expect(component.getStyle()).toEqual({ color: 'green' });
expect(component.get('customProp')).toBe('resolved-value');
expect(component.getAttributes()['data-test']).toBe('resolved-value');
});
test('should resolve styles, props, and attributes if a record is added to an existing datasource after load', () => {
const styleVar = {
type: DataVariableType,
defaultValue: 'black',
path: 'unified-source.newStyleRecord.color',
};
const propAttrVar = {
type: DataVariableType,
defaultValue: 'default-value',
path: 'unified-source.newPropRecord.value',
};
const componentProjectData: ProjectData = {
pages: [
{
frames: [
{
component: {
components: [
{
attributes: { id: 'selectorid', 'data-test': propAttrVar },
tagName: 'div',
customProp: propAttrVar,
},
],
},
},
],
},
],
styles: [{ selectors: ['#selectorid'], style: { color: styleVar } }],
dataSources: [{ id: 'unified-source', records: [] }], // Data source exists but is empty
};
editor.loadProjectData(componentProjectData);
const component = editor.getComponents().at(0); // Assert fallback to defaults because records are missing
expect(component.getStyle()).toEqual({ color: 'black' });
expect(component.get('customProp')).toBe('default-value');
expect(component.getAttributes()['data-test']).toBe('default-value');
const ds = editor.DataSources.get('unified-source');
ds?.addRecord({ id: 'newStyleRecord', color: 'purple' });
ds?.addRecord({ id: 'newPropRecord', value: 'resolved-record-value' });
expect(component.getStyle()).toEqual({ color: 'purple' });
expect(component.get('customProp')).toBe('resolved-record-value');
expect(component.getAttributes()['data-test']).toBe('resolved-record-value');
});
});
});

Loading…
Cancel
Save