diff --git a/CHANGELOG.md b/CHANGELOG.md index 04e0341f..f499a38d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Next +- Fixed: Crash with `funcsMap[propKey] is not a function` when the theme has no `textVariants` or a variant contains props that are not Restyle props. - Chore: Use npm trusted publishing and isolate package builds from publishing permissions. ## 2.4.5 - 2025-03-19 diff --git a/src/composeRestyleFunctions.ts b/src/composeRestyleFunctions.ts index a598c259..f40f6a7b 100644 --- a/src/composeRestyleFunctions.ts +++ b/src/composeRestyleFunctions.ts @@ -54,7 +54,9 @@ const composeRestyleFunctions = < // We make the assumption that the props object won't have extra prototype keys. // eslint-disable-next-line guard-for-in for (const key in props) { - const mappedProps = funcsMap[key](props, options); + const func = funcsMap[key]; + if (func === undefined) continue; + const mappedProps = func(props, options); // eslint-disable-next-line guard-for-in for (const mappedKey in mappedProps) { styles[mappedKey as keyof ViewStyle] = mappedProps[mappedKey]; diff --git a/src/test/createText.test.tsx b/src/test/createText.test.tsx index 364834c9..eba3f7cd 100644 --- a/src/test/createText.test.tsx +++ b/src/test/createText.test.tsx @@ -96,6 +96,47 @@ describe('createText', () => { ]); }); + it('ignores textVariant values that are not restyle props', () => { + const themeWithNonRestyleProp = createTheme({ + ...theme, + textVariants: { + ...theme.textVariants, + title: { + ...theme.textVariants.title, + transform: [{rotate: '45deg'}], + }, + }, + }); + + const {root} = render( + + Some text + , + ); + + expect(root.findByType(RNText).props.style).toStrictEqual([ + { + color: palette.black, + fontSize: 48, + fontWeight: 'bold', + }, + ]); + }); + + it('renders when the theme has no textVariants', () => { + const {textVariants, ...themeWithoutTextVariants} = theme; + + const {root} = render( + + Some text + , + ); + + expect(root.findByType(RNText).props.style).toStrictEqual([ + {color: palette.black}, + ]); + }); + it('passes all React Native Text Style Props', () => { const {root} = render( diff --git a/src/test/createVariant.test.ts b/src/test/createVariant.test.ts index 9dc1803c..9ddf2e2f 100644 --- a/src/test/createVariant.test.ts +++ b/src/test/createVariant.test.ts @@ -175,6 +175,28 @@ describe('createVariant', () => { expect(variant.func({}, {theme, dimensions})).toStrictEqual({}); }); + it('ignores variant values that are not restyle props', () => { + const themeWithNonRestyleProp = { + ...theme, + textVariants: { + ...theme.textVariants, + rotated: { + fontSize: 14, + transform: [{rotate: '45deg'}], + }, + }, + }; + const variant = createVariant({themeKey: 'textVariants'}); + expect( + variant.func( + {variant: 'rotated'}, + {theme: themeWithNonRestyleProp, dimensions}, + ), + ).toStrictEqual({ + fontSize: 14, + }); + }); + it('supports referencing other theme values in the variant', () => { const variant = createVariant({themeKey: 'textVariants'}); expect(