wix / react-native-ui-lib

UI Components Library for React Native
https://wix.github.io/react-native-ui-lib/
MIT License
6.56k stars 714 forks source link

Typescript add dynamic property #2691

Open theobouwman opened 1 year ago

theobouwman commented 1 year ago

Description

How can I add a dynamic property to components so no editor errors are shown

Related to

Steps to reproduce

Add dynamic prop:

ThemeManager.setComponentTheme('View', (props: any, context: any) => {
    if (props.wrap) {
        return {
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
            flexDirection: 'row',
            flexWrap: 'wrap',
        }
    }
});

Result is error in VS Code: Screenshot 2023-08-01 at 19 19 34

Expected behavior

No error.

Actual behavior

Error shown.

mrkpatchaa commented 1 year ago

You can do this

import type { ViewProps } from 'react-native-ui-lib'

interface CustomViewProps {
  wrap?: boolean
}
// ...
ThemeManager.setComponentTheme('View', (props: ViewProps & CustomViewProps, context: any) => {
    if (props.wrap) {
        return {
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
            flexDirection: 'row',
            flexWrap: 'wrap',
        }
    }
});

OR

import type { ViewProps } from 'react-native-ui-lib'

type CustomViewProps = ViewProps & {
  wrap?: boolean
}
// ...
ThemeManager.setComponentTheme('View', (props: CustomViewProps, context: any) => {
    if (props.wrap) {
        return {
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
            flexDirection: 'row',
            flexWrap: 'wrap',
        }
    }
});
theobouwman commented 1 year ago

I now have this in the themeManager.ts:

import {ThemeManager, Colors} from 'react-native-ui-lib';
import type { ViewProps } from 'react-native-ui-lib'

interface CustomViewProps {
    wrap?: boolean
}

Colors.loadDesignTokens({
    primaryColor: Colors.blue40
});

const _colors = {
    screenBG: 'white',
    textColor: Colors.grey10,
    moonOrSun: Colors.yellow30,
    mountainForeground: Colors.green30,
    mountainBackground: Colors.green50,
    $backgroundSuccess: Colors.green40,
    $backgroundSuccessLight: Colors.green70 
}

Colors.loadSchemes({
    light: _colors,
    dark: _colors
    });

ThemeManager.setComponentTheme('View', (props: ViewProps & CustomViewProps, context: any) => {
    if (props.wrap) {
        return {
            justifyContent: 'flex-start',
            alignItems: 'flex-start',
            flexDirection: 'row',
            flexWrap: 'wrap',
        }
    }
});

ThemeManager.setComponentForcedTheme('Card', {
    borderRadius: 15,
    padding: 15
})

ThemeManager.setComponentTheme('Incubator.TextField', (props: any, context: any) => {
    return {
        'text50': true,
        'color': 'grey',
    }
});

ThemeManager.setComponentTheme('Button', () => {
    return {

    }
});

And I load it in the App.tsx:

import * as React from 'react';
import { Provider } from 'react-redux';
import { store } from './src/redux/store';
import RootNavigator from './src/screens/RootNavigator';
import "./src/services";
import "./src/themeManager"

const App = () => {
  return (
      <Provider store={store}>
        <RootNavigator />
      </Provider>
  );
}

export default App;

But I am still having this issue... Screenshot 2023-08-09 at 12 38 40

mrkpatchaa commented 1 year ago

Sorry, my answer was not complete. I am not having this issue because I use a custom theme Component like this

import type { TextProps as RNUITextProps } from 'react-native-ui-lib'

import { Text as RNText } from 'react-native'
import { Text as RNUIText } from 'react-native-ui-lib'

import { CustomFamilyProps } from '@/utils/design-system'

export type TextProps = RNText['props']

export function Text(props: TextProps & RNUITextProps & CustomFamilyProps) {
  let additionalProps: CustomFamilyProps = {}
  if (!props.family && (props.h1 || props.h2 || props.h3)) {
    additionalProps = { family: 'ibm4' }
  }

  return <RNUIText {...props} {...additionalProps} />
}

...

import { Text } from '@/components/Themed'
bhandanyan-nomad commented 1 year ago

I'm running into these typescript errors on the Button and Chip (probably others too, I just notice a lot from these two specifically) components only after upgrading from 7.6.2 to the latest version. It seems like some typings have changed.

Since the ThemeManager has allowed passing custom props there should be a way to pass those props directly to UILib components without typescript errors. If there's no customization or overrides system provided out of the box, then the types should at least be defined as interfaces (instead of types) so that type augmentation can be done.

bhandanyan-nomad commented 1 year ago

It is worth noting that the main README of this project contains an example of adding a custom prop https://github.com/wix/react-native-ui-lib#step-2

// with a dynamic function
ThemeManager.setComponentTheme('Button', (props, context) => {
  // 'square' is not an original Button prop, but a custom prop that can
  // be used to create different variations of buttons in your app
  if (props.square) {
    return {
      borderRadius: 0
    };
  }
});
bhandanyan-nomad commented 1 year ago

@adids1221 @M-i-k-e-l

tagging to get guidance on how to handle this issue. Currently blocked from upgrading past 7.6.2 as a result

bhandanyan-nomad commented 1 year ago

@ethanshar

bhandanyan-nomad commented 1 year ago

@NitzanWix

bhandanyan-nomad commented 9 months ago

@NitzanWix @wixmobile @haim-wix @lidord-wix can someone please at least respond?

ethanshar commented 9 months ago

Hi @bhandanyan-nomad There's no easy way to declare a dynamic typings, we actually facing this problem ourselves. What you can do is create a shallow wrapper component on top of our components with the extra typings and use it internally.

More solutions we've been thinking of but still requires investigation and development are