From ef23b8be4d29526e4cf505cb6378b0ac1ac31f89 Mon Sep 17 00:00:00 2001 From: M-i-k-e-l Date: Wed, 31 Dec 2025 14:01:12 +0200 Subject: [PATCH 1/5] Remove unneeded defaultProps --- packages/react-native-ui-lib/src/components/icon/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/react-native-ui-lib/src/components/icon/index.tsx b/packages/react-native-ui-lib/src/components/icon/index.tsx index f012f8e32b..4eb7bcd0f5 100644 --- a/packages/react-native-ui-lib/src/components/icon/index.tsx +++ b/packages/react-native-ui-lib/src/components/icon/index.tsx @@ -129,9 +129,6 @@ const Icon = forwardRef((props: Props, ref: any) => { }); Icon.displayName = 'Icon'; -Icon.defaultProps = { - assetGroup: 'icons' -}; export default asBaseComponent>(Icon, {modifiersOptions: {margins: true}}); From 7bf1c08c33f191c1f7fe65e6576f83c73b603666 Mon Sep 17 00:00:00 2001 From: M-i-k-e-l Date: Wed, 31 Dec 2025 14:47:54 +0200 Subject: [PATCH 2/5] defaultProps on asBaseComponent --- packages/react-native-ui-lib/src/commons/asBaseComponent.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-native-ui-lib/src/commons/asBaseComponent.tsx b/packages/react-native-ui-lib/src/commons/asBaseComponent.tsx index 26c1704a89..bcdb696f42 100644 --- a/packages/react-native-ui-lib/src/commons/asBaseComponent.tsx +++ b/packages/react-native-ui-lib/src/commons/asBaseComponent.tsx @@ -55,7 +55,7 @@ function asBaseComponent(WrappedCompone }; static getDerivedStateFromError(error: any) { - UIComponent.defaultProps?.onError?.(error, WrappedComponent.defaultProps); + UIComponent.defaultProps?.onError?.(error); return {error: true}; } @@ -80,6 +80,7 @@ function asBaseComponent(WrappedCompone hoistStatics(BaseComponent, WrappedComponent); BaseComponent.displayName = WrappedComponent.displayName; BaseComponent.propTypes = WrappedComponent.propTypes; + // @ts-expect-error class component have defaultProps and functions do not and so should not be affected by this BaseComponent.defaultProps = WrappedComponent.defaultProps; const ThemeContext = ThemeManager.getThemeContext(); if (ThemeContext) { From e8d7c965b1cf1012e5aa6c356fad24fd62937350 Mon Sep 17 00:00:00 2001 From: M-i-k-e-l Date: Wed, 31 Dec 2025 14:48:27 +0200 Subject: [PATCH 3/5] Remove defaultProps (unused af far as we can tell) --- packages/react-native-ui-lib/src/commons/forwardRef.tsx | 3 --- packages/react-native-ui-lib/src/commons/withScrollEnabler.tsx | 2 -- packages/react-native-ui-lib/src/commons/withScrollReached.tsx | 2 -- 3 files changed, 7 deletions(-) diff --git a/packages/react-native-ui-lib/src/commons/forwardRef.tsx b/packages/react-native-ui-lib/src/commons/forwardRef.tsx index 38b08d8bfa..526b7469c8 100644 --- a/packages/react-native-ui-lib/src/commons/forwardRef.tsx +++ b/packages/react-native-ui-lib/src/commons/forwardRef.tsx @@ -17,10 +17,7 @@ export default function forwardRef(WrappedC const ForwardedComponent = React.forwardRef(forwardRef); hoistStatics(ForwardedComponent, WrappedComponent); - //@ts-ignore ForwardedComponent.displayName = WrappedComponent.displayName; - //@ts-ignore - ForwardedComponent.defaultProps = WrappedComponent.defaultProps; return ForwardedComponent as typeof ForwardedComponent & STATICS; } diff --git a/packages/react-native-ui-lib/src/commons/withScrollEnabler.tsx b/packages/react-native-ui-lib/src/commons/withScrollEnabler.tsx index 2bdc77ebdc..8cd4e34fbb 100644 --- a/packages/react-native-ui-lib/src/commons/withScrollEnabler.tsx +++ b/packages/react-native-ui-lib/src/commons/withScrollEnabler.tsx @@ -69,8 +69,6 @@ function withScrollEnabler(WrappedComponent: React.Componen hoistStatics(ScrollEnabler, WrappedComponent); ScrollEnabler.displayName = WrappedComponent.displayName; - //@ts-ignore - ScrollEnabler.defaultProps = WrappedComponent.defaultProps; return forwardRef(ScrollEnabler) as any; } diff --git a/packages/react-native-ui-lib/src/commons/withScrollReached.tsx b/packages/react-native-ui-lib/src/commons/withScrollReached.tsx index ea1da67579..56fde6f8ef 100644 --- a/packages/react-native-ui-lib/src/commons/withScrollReached.tsx +++ b/packages/react-native-ui-lib/src/commons/withScrollReached.tsx @@ -92,8 +92,6 @@ function withScrollReached(WrappedComponent: React.Componen hoistStatics(ScrollReachedDetector, WrappedComponent); ScrollReachedDetector.displayName = WrappedComponent.displayName; - //@ts-ignore - ScrollReachedDetector.defaultProps = WrappedComponent.defaultProps; return forwardRef(ScrollReachedDetector) as any; } From 46aaff7af4effc39a077c1f8e9a56ef24d731b99 Mon Sep 17 00:00:00 2001 From: M-i-k-e-l Date: Wed, 31 Dec 2025 14:48:51 +0200 Subject: [PATCH 4/5] Remove DocsGenerator (unused) --- .../src/helpers/DocsGenerator.js | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 packages/react-native-ui-lib/src/helpers/DocsGenerator.js diff --git a/packages/react-native-ui-lib/src/helpers/DocsGenerator.js b/packages/react-native-ui-lib/src/helpers/DocsGenerator.js deleted file mode 100644 index f3e5429768..0000000000 --- a/packages/react-native-ui-lib/src/helpers/DocsGenerator.js +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import _ from 'lodash'; - -const TAB = ' '; -const LINE_BREAK = '\n'; - -export function extractComponentInfo(instance) { - const componentName = instance.constructor.displayName; - const defaultProps = instance.constructor.defaultProps || {}; - const props = instance.props || {}; - return {componentName, defaultProps, props}; -} - -export function generateSnippet({componentName, defaultProps, props}) { - let snippet = `<${componentName}`; - - _.forEach(props, (value, key) => { - if (key === 'children') { - return; - } - let formattedValue = `{${value}}`; - if (_.isObject(value)) { - formattedValue = `{${JSON.stringify(value)}}`; - } else if (_.isString(value)) { - formattedValue = `"${value}"`; - } else if (_.isBoolean(value) && value === true) { - formattedValue = ''; - } - - const hasEmptyValue = _.isUndefined(value) || (_.isObject(value) && _.isEmpty(value)); - const hasDefaultValue = value == defaultProps[key]; // eslint-disable-line - if (!hasEmptyValue && !hasDefaultValue) { - snippet += `${LINE_BREAK}${TAB}${key}`; - if (formattedValue) { - snippet += `=${formattedValue}`; - } - } - }); - - if (props.children) { - const childrenSnippets = React.Children.map(props.children, child => { - if (_.get(child, 'type.displayName')) { - const childSnippet = - TAB + - generateSnippet({ - componentName: child.type.displayName, - props: child.props || {}, - defaultProps: child.type.defaultProps || {} - }); - return childSnippet; - } - if (typeof child === 'string') { - return child; - } - }); - snippet += `>${LINE_BREAK}${childrenSnippets.join(LINE_BREAK)}${LINE_BREAK}`; - } else { - snippet += '/>'; - } - return snippet; -} From d98d10303bd56374d438b515d4b016692ce9eec3 Mon Sep 17 00:00:00 2001 From: Miki Leib <38354019+M-i-k-e-l@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:35:54 +0200 Subject: [PATCH 5/5] Fix (most) typescript issue (#3902) * Fix (most) typescript issue * Infra/v9 tests (#3903) * Fix button and update @testing-library/react-native version * Remove unsupported modifiers methods, add docs and fix tests The old TextField was the only usage of the removed methods and it was only used by MaskedInput which is deprecated --- docs/getting-started/v8.md | 3 +- docs/getting-started/v9.md | 21 + package.json | 7 +- packages/react-native-ui-lib/package.json | 4 +- .../src/commons/__tests__/modifiers.spec.js | 36 - .../src/commons/baseComponent.tsx | 2 - .../src/commons/modifiers.ts | 21 - .../components/button/__tests__/index.spec.js | 118 ++- .../src/components/featureHighlight/index.tsx | 2 - .../src/components/hint/HintMockChildren.tsx | 2 +- .../src/components/hint/HintOld.tsx | 2 +- .../src/components/image/index.tsx | 14 +- .../__tests__/maskedInput.old.spec.tsx | 20 - ...nput.new.spec.tsx => maskedInput.spec.tsx} | 4 +- .../src/components/maskedInput/index.tsx | 137 +++- .../maskedInput/maskedInput.api.json | 1 - .../src/components/maskedInput/new.tsx | 129 ---- .../src/components/maskedInput/old.js | 82 -- .../src/components/numberInput/index.tsx | 2 +- .../picker/__tests__/index.spec.tsx | 12 +- .../src/components/picker/types.ts | 1 - .../src/components/scrollBar/index.tsx | 23 +- .../src/components/textFieldOld/index.tsx | 711 ------------------ .../src/components/view/index.tsx | 3 +- .../src/hooks/useCombinedRefs/index.ts | 1 - .../src/typings/module.d.ts | 15 +- yarn.lock | 135 +++- 27 files changed, 373 insertions(+), 1135 deletions(-) create mode 100644 docs/getting-started/v9.md delete mode 100644 packages/react-native-ui-lib/src/components/maskedInput/__tests__/maskedInput.old.spec.tsx rename packages/react-native-ui-lib/src/components/maskedInput/__tests__/{maskedInput.new.spec.tsx => maskedInput.spec.tsx} (87%) delete mode 100644 packages/react-native-ui-lib/src/components/maskedInput/new.tsx delete mode 100644 packages/react-native-ui-lib/src/components/maskedInput/old.js delete mode 100644 packages/react-native-ui-lib/src/components/textFieldOld/index.tsx diff --git a/docs/getting-started/v8.md b/docs/getting-started/v8.md index 1a29754cd7..820d60455f 100644 --- a/docs/getting-started/v8.md +++ b/docs/getting-started/v8.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 sidebar_label: Migrating v7 -> v8 title: "Migrating v7 -> v8" # path: "/getting-started/v8" @@ -7,6 +7,7 @@ title: "Migrating v7 -> v8" ## `react-native-ui-lib@8.x.x` ## General +Now supports react-native 0.77 `uilib-native` (our native library) has been moved from `dependencies` to `peerDependencies`. Make sure to `pod install` after updating. We do plan on making this optional in the future. diff --git a/docs/getting-started/v9.md b/docs/getting-started/v9.md new file mode 100644 index 0000000000..31dcbda645 --- /dev/null +++ b/docs/getting-started/v9.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 7 +sidebar_label: Migrating v8 -> v9 +title: "Migrating v8 -> v9" +# path: "/getting-started/v9" +--- +## `react-native-ui-lib@9.x.x` + +## General +Now supports react-native 0.78 and React 19 + +## Components + +### MaskedInput +Only the newer version is now available (the `migrate` prop is removed) + +## Utils + +### modifiers +extractOwnProps - removed +extractComponentProps - removed diff --git a/package.json b/package.json index fd64125a84..afa75f8de9 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "ios": "yarn workspace react-native-ui-lib ios", "android": "yarn workspace react-native-ui-lib android", "iPad": "yarn workspace react-native-ui-lib iPad", - "test": "yarn lint && yarn workspace react-native-ui-lib test", + "test": "yarn workspace react-native-ui-lib test", + "pretest": "yarn lint", "lint": "eslint packages -c .eslintrc.js --ext .tsx,.ts,.js", "lint:fix": "eslint packages -c .eslintrc.js --fix", "build:dev": "tsc --p tsconfig.dev.json", @@ -40,8 +41,8 @@ "@react-native/metro-config": "0.78.3", "@react-native/typescript-config": "0.78.3", "@shopify/flash-list": "1.7.6", - "@testing-library/react-native": "^11.5.1", - "@types/hoist-non-react-statics": "^3.3.1", + "@testing-library/react-native": "^13.3.3", + "@types/hoist-non-react-statics": "^3.3.7", "@types/jest": "^29.5.13", "@types/lodash": "^4.0.0", "@types/react": "19.0.0", diff --git a/packages/react-native-ui-lib/package.json b/packages/react-native-ui-lib/package.json index 95f880812a..462e5cb44c 100644 --- a/packages/react-native-ui-lib/package.json +++ b/packages/react-native-ui-lib/package.json @@ -64,8 +64,8 @@ "@react-native/metro-config": "0.78.3", "@react-native/typescript-config": "0.78.3", "@shopify/flash-list": "1.7.6", - "@testing-library/react-native": "^11.5.1", - "@types/hoist-non-react-statics": "^3.3.1", + "@testing-library/react-native": "^13.3.3", + "@types/hoist-non-react-statics": "^3.3.7", "@types/jest": "^29.5.13", "@types/lodash": "^4.0.0", "@types/react": "19.0.0", diff --git a/packages/react-native-ui-lib/src/commons/__tests__/modifiers.spec.js b/packages/react-native-ui-lib/src/commons/__tests__/modifiers.spec.js index 789bf2d07d..310a601b27 100644 --- a/packages/react-native-ui-lib/src/commons/__tests__/modifiers.spec.js +++ b/packages/react-native-ui-lib/src/commons/__tests__/modifiers.spec.js @@ -282,24 +282,6 @@ describe('Modifiers', () => { }); }); - // describe('extractOwnProps', () => { - // it('should extract the component props from a props object', () => { - // const props = {color: 'red', topShadow: 1, bottomShadow: 2}; - // expect(MultipleShadow.extractOwnProps(props)).toEqual({ - // topShadow: 1, - // bottomShadow: 2, - // }); - // }); - - // it('should omit props that were required to ignore', () => { - // const props = {color: 'red', topShadow: 1, bottomShadow: 2}; - // expect(MultipleShadow.extractOwnProps(props, 'topShadow')).toEqual({ - // bottomShadow: 2, - // }); - // expect(MultipleShadow.extractOwnProps(props, ['topShadow', 'bottomShadow'])).toEqual({}); - // }); - // }); - describe('extractModifiersProps', () => { it('should return all modifiers props', () => { expect(uut.extractModifierProps({ @@ -343,24 +325,6 @@ describe('Modifiers', () => { }); }); - describe('extractOwnProps', () => { - it('should extract the component props from a props object', () => { - const props = {color: 'red', prop1: 'text', prop2: 2}; - expect(uut.extractOwnProps.bind(SampleComponent)(props)).toEqual({ - prop1: 'text', - prop2: 2 - }); - }); - - it('should omit props that were required to ignore', () => { - const props = {color: 'red', prop1: 'text', prop2: 2}; - expect(uut.extractOwnProps.bind(SampleComponent)(props, 'prop1')).toEqual({ - prop2: 2 - }); - expect(uut.extractOwnProps.bind(SampleComponent)(props, ['prop1', 'prop2'])).toEqual({}); - }); - }); - describe('getThemeProps', () => { beforeEach(() => { ThemeManager.setComponentTheme('SampleComponent', undefined); diff --git a/packages/react-native-ui-lib/src/commons/baseComponent.tsx b/packages/react-native-ui-lib/src/commons/baseComponent.tsx index 2ab4affa83..73bdad4672 100644 --- a/packages/react-native-ui-lib/src/commons/baseComponent.tsx +++ b/packages/react-native-ui-lib/src/commons/baseComponent.tsx @@ -10,8 +10,6 @@ export default function baseComponent(usePure: boolean): ComponentType { styles: any; view: any; - static extractOwnProps = Modifiers.extractOwnProps; - constructor(props: any) { super(props); if (!this.styles) { diff --git a/packages/react-native-ui-lib/src/commons/modifiers.ts b/packages/react-native-ui-lib/src/commons/modifiers.ts index 1815b21305..7117654191 100644 --- a/packages/react-native-ui-lib/src/commons/modifiers.ts +++ b/packages/react-native-ui-lib/src/commons/modifiers.ts @@ -338,27 +338,6 @@ export function extractModifierProps(props: Dictionary) { return modifierProps; } -/** - * TODO: - * @deprecated switch to Modifiers#extractComponentProps - */ -export function extractOwnProps(props: Dictionary, ignoreProps: string[]) { - //@ts-ignore - const ownPropTypes = this.propTypes; - const ownProps = _.flow((props: Dictionary) => _.pickBy(props, (_value, key) => _.includes(Object.keys(ownPropTypes), key)), - props => _.omit(props, ignoreProps))(props); - - return ownProps; -} - -export function extractComponentProps(component: any, props: Dictionary, ignoreProps: string[] = []) { - const componentPropTypes = component.propTypes; - const componentProps = _.flow((props: Dictionary) => _.pickBy(props, (_value, key) => _.includes(Object.keys(componentPropTypes), key)), - props => _.omit(props, ignoreProps))(props); - - return componentProps; -} - export function getComponentName(componentDisplayName: string) { //@ts-ignore return componentDisplayName || this.displayName || this.constructor.displayName || this.constructor.name; diff --git a/packages/react-native-ui-lib/src/components/button/__tests__/index.spec.js b/packages/react-native-ui-lib/src/components/button/__tests__/index.spec.js index 722978bfa2..61b6820f48 100644 --- a/packages/react-native-ui-lib/src/components/button/__tests__/index.spec.js +++ b/packages/react-native-ui-lib/src/components/button/__tests__/index.spec.js @@ -1,5 +1,5 @@ import React from 'react'; -import renderer from 'react-test-renderer'; +import {render} from '@testing-library/react-native'; import Button from '../index'; import View from '../../view'; import {Colors, ThemeManager} from '../../../style'; @@ -12,54 +12,54 @@ describe('Button', () => { }); it('should render default button', () => { - const tree = renderer.create(