diff --git a/lib/src/Navigation.ts b/lib/src/Navigation.ts index 6794793e678..56b46a958b6 100644 --- a/lib/src/Navigation.ts +++ b/lib/src/Navigation.ts @@ -17,6 +17,9 @@ import { TouchablePreview } from './adapters/TouchablePreview'; import { LayoutRoot, Layout } from './interfaces/Layout'; import { Options } from './interfaces/Options'; import { ComponentWrapper } from './components/ComponentWrapper'; +import { OptionsProcessor } from './commands/OptionsProcessor'; +import { ColorService } from './adapters/ColorService'; +import { AssetService } from './adapters/AssetResolver'; export class NavigationRoot { public readonly Element: React.ComponentType<{ elementId: any; resizeMode?: any; }>; @@ -44,10 +47,18 @@ export class NavigationRoot { this.componentEventsObserver = new ComponentEventsObserver(this.nativeEventsReceiver); this.componentRegistry = new ComponentRegistry(this.store, this.componentEventsObserver); this.layoutTreeParser = new LayoutTreeParser(); - this.layoutTreeCrawler = new LayoutTreeCrawler(this.uniqueIdProvider, this.store); + const optionsProcessor = new OptionsProcessor(this.store, this.uniqueIdProvider, new ColorService(), new AssetService()); + this.layoutTreeCrawler = new LayoutTreeCrawler(this.uniqueIdProvider, this.store, optionsProcessor); this.nativeCommandsSender = new NativeCommandsSender(); this.commandsObserver = new CommandsObserver(); - this.commands = new Commands(this.nativeCommandsSender, this.layoutTreeParser, this.layoutTreeCrawler, this.commandsObserver, this.uniqueIdProvider); + this.commands = new Commands( + this.nativeCommandsSender, + this.layoutTreeParser, + this.layoutTreeCrawler, + this.commandsObserver, + this.uniqueIdProvider, + optionsProcessor + ); this.eventsRegistry = new EventsRegistry(this.nativeEventsReceiver, this.commandsObserver, this.componentEventsObserver); this.componentEventsObserver.registerOnceForAllComponentEvents(); diff --git a/lib/src/adapters/AssetResolver.ts b/lib/src/adapters/AssetResolver.ts new file mode 100644 index 00000000000..81a6f9cd61b --- /dev/null +++ b/lib/src/adapters/AssetResolver.ts @@ -0,0 +1,8 @@ +import * as resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; +import { ImageRequireSource } from 'react-native'; + +export class AssetService { + resolveFromRequire(value: ImageRequireSource) { + return resolveAssetSource(value); + } +} diff --git a/lib/src/adapters/ColorService.ts b/lib/src/adapters/ColorService.ts new file mode 100644 index 00000000000..69f06d4c16c --- /dev/null +++ b/lib/src/adapters/ColorService.ts @@ -0,0 +1,7 @@ +import { processColor } from 'react-native'; + +export class ColorService { + toNativeColor(inputColor: string) { + return processColor(inputColor); + } +} diff --git a/lib/src/commands/Commands.test.ts b/lib/src/commands/Commands.test.ts index 71a605b209d..a3298d323e7 100644 --- a/lib/src/commands/Commands.test.ts +++ b/lib/src/commands/Commands.test.ts @@ -8,6 +8,7 @@ import { UniqueIdProvider } from '../adapters/UniqueIdProvider.mock'; import { Commands } from './Commands'; import { CommandsObserver } from '../events/CommandsObserver'; import { NativeCommandsSender } from '../adapters/NativeCommandsSender'; +import { OptionsProcessor } from './OptionsProcessor'; describe('Commands', () => { let uut: Commands; @@ -22,12 +23,16 @@ describe('Commands', () => { mockedNativeCommandsSender = mock(NativeCommandsSender); nativeCommandsSender = instance(mockedNativeCommandsSender); + const mockedOptionsProcessor = mock(OptionsProcessor); + const optionsProcessor = instance(mockedOptionsProcessor); + uut = new Commands( nativeCommandsSender, new LayoutTreeParser(), - new LayoutTreeCrawler(new UniqueIdProvider(), store), + new LayoutTreeCrawler(new UniqueIdProvider(), store, optionsProcessor), commandsObserver, - new UniqueIdProvider() + new UniqueIdProvider(), + optionsProcessor ); }); @@ -353,7 +358,16 @@ describe('Commands', () => { const mockParser = { parse: () => 'parsed' }; const mockCrawler = { crawl: (x: any) => x, processOptions: (x: any) => x }; commandsObserver.register(cb); - uut = new Commands(mockedNativeCommandsSender, mockParser as any, mockCrawler as any, commandsObserver, new UniqueIdProvider()); + const mockedOptionsProcessor = mock(OptionsProcessor); + const optionsProcessor = instance(mockedOptionsProcessor); + uut = new Commands( + mockedNativeCommandsSender, + mockParser as any, + mockCrawler as any, + commandsObserver, + new UniqueIdProvider(), + optionsProcessor + ); }); function getAllMethodsOfUut() { diff --git a/lib/src/commands/Commands.ts b/lib/src/commands/Commands.ts index b106972fcdf..261c33b4c42 100644 --- a/lib/src/commands/Commands.ts +++ b/lib/src/commands/Commands.ts @@ -6,6 +6,7 @@ import { Options } from '../interfaces/Options'; import { Layout, LayoutRoot } from '../interfaces/Layout'; import { LayoutTreeParser } from './LayoutTreeParser'; import { LayoutTreeCrawler } from './LayoutTreeCrawler'; +import { OptionsProcessor } from './OptionsProcessor'; export class Commands { constructor( @@ -13,8 +14,9 @@ export class Commands { private readonly layoutTreeParser: LayoutTreeParser, private readonly layoutTreeCrawler: LayoutTreeCrawler, private readonly commandsObserver: CommandsObserver, - private readonly uniqueIdProvider: UniqueIdProvider) { - } + private readonly uniqueIdProvider: UniqueIdProvider, + private readonly optionsProcessor: OptionsProcessor + ) {} public setRoot(simpleApi: LayoutRoot) { const input = _.cloneDeep(simpleApi); @@ -41,7 +43,7 @@ export class Commands { public setDefaultOptions(options: Options) { const input = _.cloneDeep(options); - this.layoutTreeCrawler.processOptions(input); + this.optionsProcessor.processOptions(input); this.nativeCommandsSender.setDefaultOptions(input); this.commandsObserver.notify('setDefaultOptions', { options }); @@ -49,7 +51,7 @@ export class Commands { public mergeOptions(componentId: string, options: Options) { const input = _.cloneDeep(options); - this.layoutTreeCrawler.processOptions(input); + this.optionsProcessor.processOptions(input); this.nativeCommandsSender.mergeOptions(componentId, input); this.commandsObserver.notify('mergeOptions', { componentId, options }); diff --git a/lib/src/commands/LayoutTreeCrawler.test.ts b/lib/src/commands/LayoutTreeCrawler.test.ts index 7acc51d82ea..52f05760afa 100644 --- a/lib/src/commands/LayoutTreeCrawler.test.ts +++ b/lib/src/commands/LayoutTreeCrawler.test.ts @@ -4,6 +4,8 @@ import { LayoutType } from './LayoutType'; import { LayoutTreeCrawler, LayoutNode } from './LayoutTreeCrawler'; import { UniqueIdProvider } from '../adapters/UniqueIdProvider.mock'; import { Store } from '../components/Store'; +import { mock, instance } from 'ts-mockito'; +import { OptionsProcessor } from './OptionsProcessor'; describe('LayoutTreeCrawler', () => { let uut: LayoutTreeCrawler; @@ -11,7 +13,9 @@ describe('LayoutTreeCrawler', () => { beforeEach(() => { store = new Store(); - uut = new LayoutTreeCrawler(new UniqueIdProvider(), store); + const mockedOptionsProcessor = mock(OptionsProcessor); + const optionsProcessor = instance(mockedOptionsProcessor); + uut = new LayoutTreeCrawler(new UniqueIdProvider(), store, optionsProcessor); }); it('crawls a layout tree and adds unique id to each node', () => { @@ -202,88 +206,6 @@ describe('LayoutTreeCrawler', () => { expect(node.data.passProps).toBeUndefined(); }); - describe('navigation options', () => { - let options: Record; - let node: LayoutNode; - - beforeEach(() => { - options = {}; - node = { type: LayoutType.Component, data: { name: 'theComponentName', options }, children: [] }; - }); - - it('processes colors into numeric AARRGGBB', () => { - options.someKeyColor = 'red'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xffff0000); - }); - - it('processes colors into numeric AARRGGBB', () => { - options.someKeyColor = 'yellow'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xffffff00); - }); - - it('processes numeric colors', () => { - options.someKeyColor = '#123456'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xff123456); - }); - - it('processes numeric colors with rrggbbAA', () => { - options.someKeyColor = 0x123456ff; // wut - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xff123456); - }); - - it('process colors with rgb functions', () => { - options.someKeyColor = 'rgb(255, 0, 255)'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xffff00ff); - }); - - it('process colors with special words', () => { - options.someKeyColor = 'fuchsia'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xffff00ff); - }); - - it('process colors with hsla functions', () => { - options.someKeyColor = 'hsla(360, 100%, 100%, 1.0)'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(0xffffffff); - }); - - it('unknown colors return undefined', () => { - options.someKeyColor = 'wut'; - uut.crawl(node); - expect(node.data.options.someKeyColor).toEqual(undefined); - }); - - it('any keys ending with Color', () => { - options.otherKeyColor = 'red'; - options.yetAnotherColor = 'blue'; - options.andAnotherColor = 'rgb(0, 255, 0)'; - uut.crawl(node); - expect(node.data.options.otherKeyColor).toEqual(0xffff0000); - expect(node.data.options.yetAnotherColor).toEqual(0xff0000ff); - expect(node.data.options.andAnotherColor).toEqual(0xff00ff00); - }); - - it('keys ending with Color case sensitive', () => { - options.otherKey_color = 'red'; // eslint-disable-line camelcase - uut.crawl(node); - expect(node.data.options.otherKey_color).toEqual('red'); - }); - - it('any nested recursive keys ending with Color', () => { - options.innerObj = { theKeyColor: 'red' }; - options.innerObj.innerMostObj = { anotherColor: 'yellow' }; - uut.crawl(node); - expect(node.data.options.innerObj.theKeyColor).toEqual(0xffff0000); - expect(node.data.options.innerObj.innerMostObj.anotherColor).toEqual(0xffffff00); - }); - }); - describe('LayoutNode', () => { it('convertable from same data structure', () => { const x = { diff --git a/lib/src/commands/LayoutTreeCrawler.ts b/lib/src/commands/LayoutTreeCrawler.ts index b84250a1742..0ae1dfbb23d 100644 --- a/lib/src/commands/LayoutTreeCrawler.ts +++ b/lib/src/commands/LayoutTreeCrawler.ts @@ -1,6 +1,7 @@ import * as _ from 'lodash'; -import { OptionsProcessor } from './OptionsProcessor'; import { LayoutType } from './LayoutType'; +import { OptionsProcessor } from './OptionsProcessor'; +import { UniqueIdProvider } from '../adapters/UniqueIdProvider'; export interface Data { name?: string; @@ -15,13 +16,12 @@ export interface LayoutNode { } export class LayoutTreeCrawler { - private optionsProcessor: OptionsProcessor; constructor( - private readonly uniqueIdProvider: any, - public readonly store: any) { + private readonly uniqueIdProvider: UniqueIdProvider, + public readonly store: any, + private readonly optionsProcessor: OptionsProcessor + ) { this.crawl = this.crawl.bind(this); - this.processOptions = this.processOptions.bind(this); - this.optionsProcessor = new OptionsProcessor(store, uniqueIdProvider); } crawl(node: LayoutNode): void { @@ -29,14 +29,10 @@ export class LayoutTreeCrawler { if (node.type === LayoutType.Component) { this._handleComponent(node); } - this.processOptions(node.data.options); + this.optionsProcessor.processOptions(node.data.options); _.forEach(node.children, this.crawl); } - processOptions(options) { - this.optionsProcessor.processOptions(options); - } - _handleComponent(node) { this._assertComponentDataName(node); this._savePropsToStore(node); diff --git a/lib/src/commands/OptionsProcessor.test.ts b/lib/src/commands/OptionsProcessor.test.ts index 766fdca3ef5..ebd9011bf5b 100644 --- a/lib/src/commands/OptionsProcessor.test.ts +++ b/lib/src/commands/OptionsProcessor.test.ts @@ -2,209 +2,130 @@ import { OptionsProcessor } from './OptionsProcessor'; import { UniqueIdProvider } from '../adapters/UniqueIdProvider'; import { Store } from '../components/Store'; import * as _ from 'lodash'; +import { Options, OptionsModalPresentationStyle } from '../interfaces/Options'; +import { mock, when, anyString, instance, anyNumber, verify } from 'ts-mockito'; +import { ColorService } from '../adapters/ColorService'; +import { AssetService } from '../adapters/AssetResolver'; describe('navigation options', () => { let uut: OptionsProcessor; - let options: Record; - let store: Store; + const mockedStore = mock(Store); + const store = instance(mockedStore); + beforeEach(() => { - options = {}; - store = new Store(); - uut = new OptionsProcessor(store, new UniqueIdProvider()); - }); + const mockedAssetService = mock(AssetService); + when(mockedAssetService.resolveFromRequire(anyNumber())).thenReturn('lol'); + const assetService = instance(mockedAssetService); - it('processes colors into numeric AARRGGBB', () => { - options.someKeyColor = 'red'; - options.color = 'blue'; - uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xffff0000); - expect(options.color).toEqual(0xff0000ff); + const mockedColorService = mock(ColorService); + when(mockedColorService.toNativeColor(anyString())).thenReturn(666); + const colorService = instance(mockedColorService); - options.someKeyColor = 'yellow'; - uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xffffff00); + uut = new OptionsProcessor(store, new UniqueIdProvider(), colorService, assetService); }); - it('processes numeric colors', () => { - options.someKeyColor = '#123456'; + it('keeps original values if values were not processed', () => { + const options: Options = { + blurOnUnmount: false, + popGesture: false, + modalPresentationStyle: OptionsModalPresentationStyle.fullScreen, + animations: { dismissModal: { alpha: { from: 0, to: 1 } } }, + }; uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xff123456); - - options.someKeyColor = 0x123456ff; // wut + expect(options).toEqual({ + blurOnUnmount: false, + popGesture: false, + modalPresentationStyle: OptionsModalPresentationStyle.fullScreen, + animations: { dismissModal: { alpha: { from: 0, to: 1 } } }, + }); + }); + + it('processes color keys', () => { + const options: Options = { + statusBar: { backgroundColor: 'red' }, + topBar: { background: { color: 'blue' } }, + }; uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xff123456); + expect(options).toEqual({ + statusBar: { backgroundColor: 666 }, + topBar: { background: { color: 666 } }, + }); }); - it('process colors with rgb functions', () => { - options.someKeyColor = 'rgb(255, 0, 255)'; + it('processes image keys', () => { + const options: Options = { + backgroundImage: 123, + rootBackgroundImage: 234, + bottomTab: { icon: 345, selectedIcon: 345 }, + }; uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xffff00ff); + expect(options).toEqual({ + backgroundImage: 'lol', + rootBackgroundImage: 'lol', + bottomTab: { icon: 'lol', selectedIcon: 'lol' }, + }); }); - it('process colors with special words', () => { - options.someKeyColor = 'fuchsia'; - uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xffff00ff); - }); + it('calls store if component has passProps', () => { + const passProps = { some: 'thing' }; + const options = { topBar: { title: { component: { passProps, name: 'a' } } } }; - it('process colors with hsla functions', () => { - options.someKeyColor = 'hsla(360, 100%, 100%, 1.0)'; uut.processOptions(options); - expect(options.someKeyColor).toEqual(0xffffffff); + verify(mockedStore.setPropsForId('CustomComponent1', passProps)).called(); }); - it('unknown colors return undefined', () => { - options.someKeyColor = 'wut'; - uut.processOptions(options); - expect(options.someKeyColor).toEqual(undefined); - }); + it('generates componentId for component id was not passed', () => { + const options = { topBar: { title: { component: { name: 'a' } } } }; - it('any keys ending with Color', () => { - options.otherKeyColor = 'red'; - options.yetAnotherColor = 'blue'; - options.andAnotherColor = 'rgb(0, 255, 0)'; uut.processOptions(options); - expect(options.otherKeyColor).toEqual(0xffff0000); - expect(options.yetAnotherColor).toEqual(0xff0000ff); - expect(options.andAnotherColor).toEqual(0xff00ff00); - }); - it('keys ending with Color case sensitive', () => { - options.otherKey_color = 'red'; // eslint-disable-line camelcase - uut.processOptions(options); - expect(options.otherKey_color).toEqual('red'); + expect(options).toEqual({ + topBar: { title: { component: { name: 'a', componentId: 'CustomComponent1' } } }, + }); }); - it('any nested recursive keys ending with Color', () => { - options.topBar = { textColor: 'red' }; - options.topBar.innerMostObj = { anotherColor: 'yellow' }; - uut.processOptions(options); - expect(options.topBar.textColor).toEqual(0xffff0000); - expect(options.topBar.innerMostObj.anotherColor).toEqual(0xffffff00); - }); + it('copies passed id to componentId key', () => { + const options = { topBar: { title: { component: { name: 'a', id: 'Component1' } } } }; - it('resolve image sources with name/ending with icon', () => { - options.icon = 'require("https://wix.github.io/react-native-navigation/_images/logo.png");'; - options.image = 'require("https://wix.github.io/react-native-navigation/_images/logo.png");'; - options.myImage = 'require("https://wix.github.io/react-native-navigation/_images/logo.png");'; - options.topBar = { - myIcon: 'require("https://wix.github.io/react-native-navigation/_images/logo.png");', - myOtherValue: 'value' - }; uut.processOptions(options); - // As we can't import external images and we don't want to add an image here - // I assign the icons to strings (what the require would generally look like) - // and expect the value to be resolved, in this case it doesn't find anything and returns null - expect(options.icon).toEqual(null); - expect(options.topBar.myIcon).toEqual(null); - expect(options.image).toEqual(null); - expect(options.myImage).toEqual(null); - expect(options.topBar.myOtherValue).toEqual('value'); + expect(options).toEqual({ + topBar: { title: { component: { name: 'a', id: 'Component1', componentId: 'Component1' } } }, + }); }); - it('passProps for Buttons options', () => { + it('calls store when button has passProps and id', () => { const passProps = { prop: 'prop' }; - options.rightButtons = [{ passProps, id: '1' }]; - - uut.processOptions({ o: options }); - - expect(store.getPropsForId('1')).toEqual(passProps); - }); - - it('passProps for custom component', () => { - const passProps = { color: '#ff0000', some: 'thing' }; - options.component = { passProps, name: 'a' }; - - uut.processOptions({ o: options }); - - expect(store.getPropsForId(options.component.componentId)).toEqual(passProps); - expect(Object.keys(options.component)).not.toContain('passProps'); - }); - - it('generate component id for component in options', () => { - options.component = { name: 'a' }; - - uut.processOptions({ o: options }); - - expect(options.component.componentId).toBeDefined(); - }); - - it('passProps from options are not processed', () => { - const passProps = { color: '#ff0000', some: 'thing' }; - const clonedProps = _.cloneDeep(passProps); - options.component = { passProps, name: 'a' }; + const options = { topBar: { rightButtons: [{ passProps, id: '1' }] } }; uut.processOptions(options); - expect(store.getPropsForId(options.component.componentId)).toEqual(clonedProps); - }); - it('pass supplied componentId for component in options', () => { - options.component = { name: 'a', id: 'Component1' }; - - uut.processOptions({ o: options }); - - expect(options.component.componentId).toEqual('Component1'); + verify(mockedStore.setPropsForId('1', passProps)).called(); }); - it('passProps must be with id next to it', () => { + it('do not touch passProps when id for button is missing', () => { const passProps = { prop: 'prop' }; - options.rightButtons = [{ passProps }]; - - uut.processOptions({ o: options }); - - expect(store.getPropsForId('1')).toEqual({}); - }); + const options = { topBar: { rightButtons: [{ passProps } as any] } }; - it('processes Options object', () => { - options.someKeyColor = 'rgb(255, 0, 255)'; - options.topBar = { textColor: 'red' }; - options.topBar.innerMostObj = { anotherColor: 'yellow' }; - - uut.processOptions({ o: options }); - - expect(options.topBar.textColor).toEqual(0xffff0000); - }); - - it('undefined value return undefined ', () => { - options.someImage = undefined; uut.processOptions(options); - expect(options.someImage).toEqual(undefined); + expect(options).toEqual({ topBar: { rightButtons: [{ passProps }] } }); }); - it('omits passProps when processing options', () => { - const passProps = { + it('omits passProps when processing buttons or components', () => { + const options = { topBar: { - rightButtons: [ - { - passProps: {}, - id: 'btn1' - }, - ], - leftButtons: [ - { - passProps: {}, - id: 'btn2' - } - ], - title: { - component: { - passProps: {} - } - }, - background: { - component: { - passProps: {} - } - } - } + rightButtons: [{ passProps: {}, id: 'btn1' }], + leftButtons: [{ passProps: {}, id: 'btn2' }], + title: { component: { name: 'helloThere1', passProps: {} } }, + background: { component: { name: 'helloThere2', passProps: {} } }, + }, }; - uut.processOptions(passProps); - expect(passProps.topBar.rightButtons[0].passProps).toBeUndefined(); - expect(passProps.topBar.leftButtons[0].passProps).toBeUndefined(); - expect(passProps.topBar.title.component.passProps).toBeUndefined(); - expect(passProps.topBar.background.component.passProps).toBeUndefined(); + uut.processOptions(options); + expect(options.topBar.rightButtons[0].passProps).toBeUndefined(); + expect(options.topBar.leftButtons[0].passProps).toBeUndefined(); + expect(options.topBar.title.component.passProps).toBeUndefined(); + expect(options.topBar.background.component.passProps).toBeUndefined(); }); }); diff --git a/lib/src/commands/OptionsProcessor.ts b/lib/src/commands/OptionsProcessor.ts index 1611f592a11..cf759a5ab3f 100644 --- a/lib/src/commands/OptionsProcessor.ts +++ b/lib/src/commands/OptionsProcessor.ts @@ -1,37 +1,54 @@ import * as _ from 'lodash'; -import { processColor } from 'react-native'; -import * as resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import { Store } from '../components/Store'; import { UniqueIdProvider } from '../adapters/UniqueIdProvider'; +import { ColorService } from '../adapters/ColorService'; +import { AssetService } from '../adapters/AssetResolver'; +import { Options } from '../interfaces/Options'; export class OptionsProcessor { - constructor(public store: Store, public uniqueIdProvider: UniqueIdProvider) { } + constructor( + private store: Store, + private uniqueIdProvider: UniqueIdProvider, + private colorService: ColorService, + private assetService: AssetService, + ) {} - public processOptions(options: Record) { - _.forEach(options, (value, key) => { - if (!value) { return; } + public processOptions(options: Options) { + this.processObject(options); + } + + private processObject(objectToProcess: object) { + _.forEach(objectToProcess, (value, key) => { + if (!value) { + return; + } - this.processComponent(key, value, options); - this.processColor(key, value, options); - this.processImage(key, value, options); + this.processComponent(key, value, objectToProcess); + this.processColor(key, value, objectToProcess); + this.processImage(key, value, objectToProcess); this.processButtonsPassProps(key, value); if (!_.isEqual(key, 'passProps') && (_.isObject(value) || _.isArray(value))) { - this.processOptions(value); + this.processObject(value); } }); } private processColor(key: string, value: any, options: Record) { if (_.isEqual(key, 'color') || _.endsWith(key, 'Color')) { - options[key] = processColor(value); + options[key] = this.colorService.toNativeColor(value); } } private processImage(key: string, value: any, options: Record) { - if (_.isEqual(key, 'icon') || _.isEqual(key, 'image') || _.endsWith(key, 'Icon') || _.endsWith(key, 'Image')) { - options[key] = resolveAssetSource(value); + if ( + _.isEqual(key, 'icon') || + _.isEqual(key, 'image') || + _.endsWith(key, 'Icon') || + _.endsWith(key, 'Image') + ) { + options[key] = this.assetService.resolveFromRequire(value); } } @@ -52,7 +69,7 @@ export class OptionsProcessor { if (value.passProps) { this.store.setPropsForId(value.componentId, value.passProps); } - options[key] = _.omit(value, 'passProps'); + options[key].passProps = undefined; } } }