Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-fela: change connect(mapStylesToProps) to be connect(rules) #260

Merged
merged 1 commit into from
May 17, 2017

Conversation

ahdinosaur
Copy link
Contributor

@ahdinosaur ahdinosaur commented May 14, 2017

hey 🐱

this is a proposal for a BREAKING CHANGE to react-fela.

the current connect takes a single argument mapStylesToProps which is a function of shape (props) => (renderer) => styles, where styles is an object of classNames mapped by style name.

i propose we change connect to take a single argument rules which is an object of rules mapped by style name.

for example, the current way:

const mapStylesToProps = (props) => (renderer) => ({
  container: renderer.renderRule(({ color }) => ({
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    backgroundColor: color
  }, { color: props.color })),
  button: renderer.renderRule(() => ({
    marginTop: '20px'
  })
})

const connectedComponent = connect(mapStylesToProps)(Component)

the proposed new way:

const rules = {
  container: ({ color }) => ({
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    backgroundColor: color
  }),
  button: () => ({
    marginTop: '20px'
  })
})

const connectedComponent = connect(rules)(Component)

why?

  • matches better with createComponent api, which takes a single rule.
  • removes renderer.renderRule boilerplate (i'm curious, does anyone have a use case where they need to call something other than renderer.renderRule?)
  • makes it nice and easy to have style files with fela rules alongside your react components, so you can mix and match rules as you wish. (in the current way, you have rules then you have to make another function mapStylesToProps which is separate)

what do people think about this idea?

if people think this is a good idea, i'm happy to update the respective documentation and change the code to pass the linter.

thanks for listening. ❤️

/cc @iainkirkpatrick

@ahdinosaur
Copy link
Contributor Author

ahdinosaur commented May 14, 2017

i'm curious, does anyone have a use case where they need to call something other than renderer.renderRule?

ah, now i see the examples/react/components/Header.js uses renderer.renderKeyframe in connect(mapStylesToProps). i wonder if we could instead support this use case by adding a second argument to connect which is given the renderer and can return an object of additional properties to add to the rule calls, or something like that. but also brings up the question how you'd do this if you prefer the createComponent api, since i guess i saw the difference between createComponent and connect being only in taste not functionality.

@robinweser
Copy link
Owner

Hey @ahdinosaur,
First of all thanks for your PR! I would like to check the API in detail later and decide if I can find any downside actually.
Would also love to hear some other opinions @johanneslumpe @tajo @tiagojsalmeida

For now I can also point you to two other resources:
E.g. there's this one that actually "does" most of the things you're proposing: https://github.com/dustin-H/fela-styles-connector and it can be used together with fela-stylesheet perfectly.

And about the second comment regarding the renderer.renderKeyframe. That's basically the reason why this API was built that way - to allow any renderer. calls without a strict API. But nowaydays, we can actually solve this with an yet undocumented feature of rules. You can access the renderer through a second parameter:

const rule = ({ fontSize }, renderer) => ({
  fontSize,
  color: 'red',
  animationName: renderer.renderKeyframe(...)
})

Also there'll soon be a plugin that allows to inline keyframes and fonts: #238 which will be released with the next update.

So for now: I really like how it simplifies the API and am more than happy to improve the connect API soon :)

@robinweser
Copy link
Owner

Ok, I am convinced this makes it much simpler! Great one =)

@robinweser robinweser merged commit 2d1b7f1 into robinweser:master May 17, 2017
@ahdinosaur
Copy link
Contributor Author

yay thanks @rofrischmann 🕺 💖 🌸

@tiagojsalmeida
Copy link
Contributor

It does look pretty good ;)

@queckezz
Copy link

Much simpler, thanks @ahdinosaur! ✨ This will be even more amazing together with fela-plugin-embedded

Here's the connect implementation for the people wanting to try out the api with the current fela@4.3.5.

import { connect as felaConnect } from 'react-fela'

export default connect

function connect (rules) {
  const mapStylesToProps = (props) => (renderer) => {
    return Object.keys(rules).reduce((acc, key) => ({
      ...acc,
      [key]: renderer.renderRule(rules[key], props)
    }), {})
  }

  return felaConnect(mapStylesToProps)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants