glamorous-native icon indicating copy to clipboard operation
glamorous-native copied to clipboard

Safer prop forwarding

Open atticoos opened this issue 8 years ago • 7 comments

Prop forwarding is currently using a naive approach of verifying the property is not a style prop name: src/is-style-prop

It should verify the property is allowed by the component. A trivial solution here would be to check the type of component (eg, a ListView), and verify the property exists in the component's propTypes

atticoos avatar May 17 '17 04:05 atticoos

I can look into this. I noticed that this isn't working though:

const BigText = glamorous.text({fontSize: 20})

<BigText color='blue' >Hi</BigText>

The fontSize is 20 but the color is not blue. I'll look into that as well.

ssomnoremac avatar May 18 '17 23:05 ssomnoremac

That should be the same behavior as in glamorous, if @kentcdodds could confirm.

"properties as styles" is only supported when the GlamorousComponent class has propsAreStyleOverrides = true defined on it.

Your example would work with the following changes:

 const BigText = glamorous.text({fontSize: 20})
+BigText.propsAreStyleOverrides = true

 <BigText color='blue' >Hi</BigText>

The built-in components all have propsAreStyleOverrides enabled, which is why the following works

<glamorous.Text color="blue">Blue text</glamorous.Text>

atticoos avatar May 19 '17 00:05 atticoos

Confirmed, this is by design :+1:

kentcdodds avatar May 19 '17 06:05 kentcdodds

Note: another way to accomplish what you're after would be:

const BigText = glamorous.text({fontSize: 20})

<BigText css={{color: 'blue'}}>Hi</BigText>

kentcdodds avatar May 19 '17 06:05 kentcdodds

Note: another way to accomplish what you're after would be:

const BigText = glamorous.text({fontSize: 20})

<BigText css={{color: 'blue'}}>Hi</BigText>

I'm fairly new to react-native and glamorous-native, so please excuse me if I'm missing something super obvious, but I'm wondering if the above example (with the css={{color: 'blue'}} prop) has an equivalent in glamorous-native? If not, are there any plans to add the css prop to glamorous-native components?

My current preference with glamorous on the web is to use the css prop over the component factories because it allows you to have styles immediately visible in-context inside your component tree, but still encapsulated inside a single prop so you can turn off propsAreStyleOverrides and keep your component API explicit.

Right now I'm using a custom shim over the glamorous-native factories to pick off the css prop and apply it as args to each factory to maintain a consistent API:

const create = React.createElement

const glamorousFactoryArgs = (css) => F.unnest(F.append(css, []))

const withCssProp = (glamorousFactory) => ({ css, ...props }) =>
  create(glamorousFactory(...glamorousFactoryArgs(css)), props)

But it'd be great if there was an officially supported way to accomplish the same thing.

I'm totally willing to take some time to look into this and make a PR if this is something desirable but not high enough priority for the primary maintainers to work on at the moment.

lewisl9029 avatar Sep 11 '17 02:09 lewisl9029

Hi @lewisl9029 -- React Native uses the style prop to pass styles to components. It's essentially equivalent to css, but it also accepts arrays.

Example:

const BigText = glamorous.text({fontSize: 20})

<BigText style={{color: 'blue'}}>Hi</BigText>

atticoos avatar Sep 11 '17 15:09 atticoos

Ah that makes a ton of sense. For some reason I had the impression that you could only use style in React Native with the stylesheet references from the props of whatever gets returned by StyleSheet.create(). But if you could simply pass in plain style objects, that would be perfect.

lewisl9029 avatar Sep 12 '17 02:09 lewisl9029