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

Add ClassNames component #828

Merged
merged 9 commits into from
Sep 27, 2018
Merged

Conversation

emmatown
Copy link
Member

@emmatown emmatown commented Aug 29, 2018

What:
Add Style ClassNames component.

css and cx work just like the exports from emotion except they work with emotion 10's SSR and the options that can be provided via context.

It also accepts the theme.

<ClassNames>
  {({ css, cx, theme }) => {
    let secondClassButItsInsertedFirst = css`
      color: green;
    `
    let firstClassButItsInsertedSecond = css`
      color: hotpink;
    `

    return (
      <div
        className={cx(
          firstClassButItsInsertedSecond,
          'some-other-class',
          secondClassButItsInsertedFirst
        )}
      />
    )
  }}
</ClassNames>

Why:

To account for cases when components accept props like wrapperClassName and etc.

How:

Checklist:

I'm not totally sure about the API, the name of the component and whether it should be in the core package. I'd love to hear people's thoughts on it!!

Note: This is based on #824 not master.

break
case 'function':
if (process.env.NODE_ENV !== 'production') {
console.error(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed? it's already "next major version of Emotion" :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I made this a while ago and copied classnames from v9.

| { [key: string]: boolean }
| Array<ClassNameArg>

let classnames = (args: Array<ClassNameArg>): string => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can u explain more why this is duplicated? I suspect it's like a global caching registry issue, but couldnt this share the implementation with original cx, css & merge?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m just lazy, I think I’ll move it and merge into @emotion/utils. There’s no point in sharing css and cx since they need slightly different things in here and in create-emotion.

@emmatown
Copy link
Member Author

emmatown commented Aug 30, 2018

Just FYI, I’m mainly looking for a review of the API rather than code review.

@Andarist
Copy link
Member

Could you explain a little bit more why this is needed for SSR? I'm not too familiar with its intricacies

@emmatown
Copy link
Member Author

Because there needs to be somewhere to render the style tags and the exact styles that need to be rendered there must be known when the style tag is being rendered, that's not possible if using something like css from emotion.(by SSR, I'm referring to emotion 10's automatic SSR)

@Andarist
Copy link
Member

that's not possible if using something like css from emotion

Why? Isnt the css call synchronous anyway?

@emmatown
Copy link
Member Author

Let's say you have this component, how is it possible to do automatic SSR?

let SomeComponent = () => (
  <div
    className={css`
      color: hotpink;
    `}
  />
)

@emmatown
Copy link
Member Author

Also, I just want to repeat this, this is only intended for cases when components accept props like wrapperClassName and etc.

@Andarist
Copy link
Member

Ok, I get now how it's impossible for auto-SSR.

The API looks good, although it slightly shows that even though current approach brings easier SSR to the table it also has its drawbacks such as having to know that sometimes <Style/> has to be used.

Also - not sure what's the best name for this component, maybe <ServerStyle/>?

@emmatown
Copy link
Member Author

emmatown commented Aug 30, 2018

This isn't just for auto-SSR though, it's also for providing consuming the cache via context so that things like working in iframes, getting the theme and etc. work.

The ServerStyle name doesn't really make sense since it's not just for SSR.

@Andarist
Copy link
Member

This isn't just for auto-SSR though, it's also for providing the cache via context so that things like working in iframes, getting the theme and etc. work.

Is this meant to be a replacement for previously presented APIs? You've already demoed i.e. rendering to iframes etc.

Sorry for asking so many questions, I'm not too familiar with v10 APIs - lacking a "big picture" and how existing pieces fit together.

@emmatown
Copy link
Member Author

No, this isn't meant to be a replacement for the css prop or styled, it's meant for for the small number of cases that they can't solve.

Sorry, when I said providing the cache via context I meant consuming it via context.

@Andarist
Copy link
Member

Ok, I think I get it now 👍 The only confusing part for me is the name of the component - for a css-in-js a component named <Style/> is rather confusing, like - it doesn't tell me much what it exactly do. A name like <Emotion/> (although not descriptive) would tell me more about what I can do with it. This might be though solely because I'm already accustomed to what emotion package provides.

From what I get it seems that we are going to have now 2 context consumer types - one holds registry, stylis, sheet etc and accounts for preferred way of writing "idiomatic" emotion (it doesnt provide things like css, because those are discouraged in react setting) and we have this other consumer - <Style/> which provides access to those "discouraged" helpers. Did I get this right?

@emmatown
Copy link
Member Author

Yeah, that's mostly correct though this isn't very different from the other consumers, they all work in the same way, they just provide different APIs to insert styles. This API is just less convenient but more flexible.

I just thought of another name, ClassNames, any thoughts on that?

@Andarist
Copy link
Member

I just thought of another name, ClassNames, any thoughts on that?

I like it better 👍

@emmatown emmatown changed the title Add Style component Add ClassNames component Aug 31, 2018
@tkh44
Copy link
Member

tkh44 commented Aug 31, 2018

I like this name better.

I just thought of this, but what if it was just called Emotion

@emmatown
Copy link
Member Author

@Andarist suggested that too, I feel like it doesn’t convey much meaning about what it does though.

@Ailrun
Copy link
Member

Ailrun commented Aug 31, 2018

For me, it's also hard to understand. How about SerialStyles or something like that?

@emmatown
Copy link
Member Author

I like ClassNames because it conveys that it’s about class names since what it does is let you get a class name from some styles and merge together class names.

I don’t really get what SerialStyles means and how it would convey what this component does

@Ailrun
Copy link
Member

Ailrun commented Aug 31, 2018

Oh, I thought about css props part only. With cx props, what you said make sense.

but still... does ClassNames really convey the differences of css props from original css function?

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

css props is different original css, so the component name should convey the differences, shouldn't it?

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

There isn’t really a difference between the css function in this component and the css function in v9 except for the implementation.

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

Are you talking about the css prop in emotion 10 or the css function in this component?

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

It's different in SSR, isn't it?

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

Kind of but the usage of it is the same which is the part that people care about

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

I mean the difference between css function from @emotion/core and from props of this component.

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

(I believe) I know interfaces of those functions are same, but if it work differently in some sense, it should convey those differences as a name, shouldn't it?

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

If it works the same from the user’s perspective, why should they have to learn a new name for something that does the same thing?

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

Oh sorry, didn’t see your comment about css from @emotion/core, yep that makes sense, got any name suggestions for it then?

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

Actually, that's where my SerialStyle comes from, since I thought those difference should be reflected in the name of component, not a name of actual props.
My reasoning is like following.

  1. If we have different name for css function from @emotion/core and the css function for the children of this component, refactoring codes those use css function becomes harder.
  2. But IMO, since there are differences, those difference should be reflected somewhere.
  3. Where would be appropriate for this? I cannot think other than component name.

But what you said in #828 (comment) makes sense, so I need to think more about this.

However, if those refactoring cannot make sense from the first stage, then renaming css function for children of this component could be an option.

@emmatown
Copy link
Member Author

emmatown commented Sep 1, 2018

If we have different name for css function from @emotion/core and the css function for the children of this component, refactoring codes those use css function becomes harder.

css from @emotion/core and the css function for the children of this component return totally different thing things though, the former returns a description of the styles while the latter returns a class name.

@Ailrun
Copy link
Member

Ailrun commented Sep 1, 2018

Oh, yes, then we don't need to worry about refactoring. Then instead of concerning about new name for component, giving appropriate name for css in this component would be better. Thank you for enlightening.

@TrySound
Copy link
Contributor

Guys, there is a better solution than wrapping every component with another one render prop.

We can have the same api but with some requirements about where functions may be called.

import * as React from 'react';
import { Provider, css } from '@emotion/contextual';

export const Component = () => (
  <Provider>
    <div className={css({ width: 100, height: 100, background: '#000' })}>
      Content
    </div>
  </Provider>
)

The point here is that since 16.5 we are able to consume context with Context.unstable_read, which works in render phase. This api actually doesn't work with ssr yet (that's why it's unstable), but we already can start experiments on client side.

Ref facebook/react#13139

@emmatown
Copy link
Member Author

This component doesn’t only need context though, it also needs to render elements.

@pksunkara
Copy link
Contributor

This is needed for emotion to work with /~https://github.com/reactjs/react-modal. Check this commit in @storybooks.

@codecov
Copy link

codecov bot commented Sep 27, 2018

Codecov Report

Merging #828 into reimplement-vanilla-emotion will decrease coverage by 0.77%.
The diff coverage is 72.72%.

Impacted Files Coverage Δ
packages/core/src/context.js 100% <100%> (ø) ⬆️
packages/core/src/class-names.js 72.22% <72.22%> (ø)

@emmatown
Copy link
Member Author

I'm gonna merge this into #824 because I want to try some stuff out. If anyone has any comments on it, you can still leave them here though.

@emmatown emmatown merged commit 915fff8 into reimplement-vanilla-emotion Sep 27, 2018
@emmatown emmatown deleted the style-component branch September 27, 2018 23:09
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.

6 participants