Coder Social home page Coder Social logo

paypal / glamorous Goto Github PK

View Code? Open in Web Editor NEW
3.6K 59.0 209.0 1.28 MB

DEPRECATED: ๐Ÿ’„ Maintainable CSS with React

Home Page: https://glamorous.rocks

License: MIT License

JavaScript 71.35% TypeScript 28.65%
css-in-js glamor react styled-components glamorous

glamorous's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

glamorous's Issues

concat forwardProps option for wrapped components

We should probably do the same to forwardProps that we do to styles here. Because otherwise you have to do this:

const compProps = ['a', 'b']
const MyComp = glamorous(Comp, {forwardProps: compProps})()
const MyWrapperComp = glamorous(MyComp, {forwardProps: compProps})()

I would prefer to only have to do:

const compProps = ['a', 'b']
const MyComp = glamorous(Comp, {forwardProps: compProps})()
const MyWrapperComp = glamorous(MyComp)()

And the compProps are forwarded along because the wrapping MyComp has defined them as acceptable props to be forwarded.

Can we make it possible to use the `css` prop on glamorous.Div, etc?

Problem description:

I would like to be able to use css prop or something similar on built-in GlamorousComponents. My use case is for dynamically generated keys. This is also a great way to write styles quickly.

const { Div } = glamorous;

export default ({ theme }) => (
  <Div
    css={{
      cursor: 'pointer',
      fill: theme.color.blue[0],
      height: 27,
      transition: 'all 200ms ease',
      width: 90,
      [theme.breakpoints.mq[1]]: {
        height: 27,
        width: 90,
      },
      [theme.breakpoints.mq[2]]: {
        height: 40,
        width: 134,
      },
      [theme.breakpoints.mq[3]]: {
        height: 50,
        width: 165,
      },
    }}
  >
    <Logo />
  </Div>
);

Right now, in our codebase, we just have a set of helpers like export Div = glamorous.div(). It would be nice if we could build this functionality in. I have no problem doing the work for a PR, but I would want to know which strategy would be used to enable something like this.

If something like this is built in and I missed it please point it out ๐Ÿ˜…

textArea vs. textarea

  • glamorous version: 3.13.1
  • glamor version: 2.20.24
  • react version: 15.5.4

Relevant code.

import glamorous from 'glamorous'

const CorrectTextArea = glamorous.textarea(); // => renders as expected with props
const IncorrectTextArea = glamorous.textArea(); // => renders as a textarea without props

What you did:

I wanted a glamorous textArea, and accidentally used glamorous.textArea(), instead of glamorous.textarea().

What happened:

textArea is a valid SVG tag, so glamorous didn't throw.

From what I saw, it seems like React Components are case-insensitive (other than the first letter). React renders <textArea />, <textarea />, <tEXTAREA> all the same (when not wrapped inside an <svg /> tag).

Reproduction:

Link to Sandbox

Problem description:

I was confused at first because my glamorous.textArea() still rendered as expected, except none of my props were getting passed down. This is because of how our should-forward-property function is running its check.

Suggested solution:

One solution is to add a conditional inside of should-forward-property to handle this.
However, I'm not sure if this is a case that we want to handle at all. Should we just expect the user to know the correct case-sensitive spelling for textarea?

`noValidate` attribute not supported on `form`

  • glamorous version: ^3.7.1
  • glamor version: ^2.20.24
  • react version: ^15.5.4

Relevant code.

const Form = glamorous.form({});
<Form noValidate />

What you did:

See above code

What happened:

No novalidate attr added

Make CSSProperties interface exportable for TypeScript

Please let me know if below does not make sense :)

Problem description:
No exported member when doing this:
import glamorous, { CSSProperties } from 'glamorous';

Suggested solution:
export CCSProperties in main glamorous definition file

I'll submit a PR :)

Improve documentation for component composition and fix `css` prop docs

I've been using glamorous in a few test applications and got a bit stuck when trying to work out the best way of doing component composition. I couldn't find anything related to this in the documentation so thought about opening this "issue".

  • glamorous version: 3.5.0
  • glamor version: 2.20.24
  • react version: 15.5.4

Reproduction:

https://codesandbox.io/s/OyM7DoxLg

Problem description:

I couldn't find an easy way of using the styles from a glamorous component without having to create a functional component. Something like styled-components does with the styled() helper.

Is this actually possible to do at the moment?

Suggested solution:

In the sandbox I suggested a couple of options, but I'm not sure which would be the best.

Doing something like

const LargeText = glamorous.div([
   Text,
   { fontSize: 24 }
]);

would give the flexibility of using a different HTML element if needed, which might be useful.

But going on the styled-components route of using something like

const LargeText = withStyles([Text, { fontSize: 24 }]);

keeps things simple. I used withStyles in line with withTheme but alternatively it could maybe be simply glamorous([Text, { fontSize: 24 }]) since the HTML element would be inferred from the Text component. This could have some issues when composing more than one component so not sure about that.

Side note

I think I might have found a bug with cssOverrides in the sandbox I posted above. If that's the case I can open a separate issue if you want, but maybe I'm just expecting a different behaviour.

Thanks!

Support all of jsxstyle props

jsxstyle has this which I think is rad:

var MyComponent = React.createClass({
  render: function() {
    return <Block color="red" hoverColor="yellow">Hello, world!</Block>;
  }
});

We should look into supporting that for our "Element Components" (glamorous.Div, glamorous.Img, etc).

Border-Color properties acting strangely based on the amount of CSS properties on the element.

  • glamorous version: 1.0.1

Relevant code or config. Or even better, [a reproduction][help-pen]

https://codesandbox.io/s/48EKDv5wg

What you did:

Was testing compatibility with polished (polished.js.org) and came across a strange bug with border-colors.

Problem description:

It seems to only set one of the directional properties properly while setting the remaining to initial.
As seen here: http://d.pr/i/7ng6/53ZbyvnT

Adding properties after the border-color properties affects which property is set properly, until adding enough eventually means all are set to initial. Move the border-color declarations to the top and they all work.

This happens with both the camelCased versions of the property names as well as the hyphenated versions, with or without polished.

Idea: Make a babel plugin to extract static styles to a CSS file

Bringing this comment into its own issue:


I think that we could maybe write a babel plugin to take this:

const MyDiv = glamorous.div({padding: 20}, ({big}) => ({fontSize: big ? 20 : 30}))

to this:

const MyDiv = glamorous.div('css-dfk22d34', ({big}) => ({fontSize: big ? 20 : 30}))

Where the static styles are pre-processed and the resulting styles are extracted to a separate stylesheet, and we work with glamor's rehydration API to hook things up again. We'd need to update the glamorousComponentFactory API to accept a string class name, but that should be trivial. In any case, this would probably speed things up significantly.

I just realized that based on the way we merge glamor class names with the styles they represent into a single class name may cause issues with this, but let's start with components that have static styles only, then maybe we can get it working with a combination of static and dynamic styles.

Anyone wanna write a plugin for this? If you've not made a Babel plugin before or worked with ASTs before, you can learn about it from my talk :)

Create and add logo

@mxstbr says he's cool with this:

glamorous

It's obviously inspired by styled-components:

styled-components

Here's how I made it:

<div style="
  width: 300px;
  height: 300px;
  display: flex;
  margin: auto;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-size: 60px;
  font-family: cursive;
  border: 2px solid;
">
  <div>&lt; ๐Ÿ’„ &gt;</div>
  <div>glamorous</div>
</div>

Thanks Max!

Add support for `innerRef`

Instead of having to convolutedly wrap components to gain access to the inner element / component of a Glamorous-wrapped node it would be nice to have a convenience prop such as innerRef that would proxy down to the underlying element's ref property.

i.e.:

import { Div } from 'glamorous'

<Div innerRef={(node) => { console.log(node) }} />

Support context

It'd be useful to be able to do:

const MyDiv = glamorous.div((props, theme, context) => ({ /* my styles */ }))
MyDiv.contextTypes = { /* context types */ }

I've not really used context a ton, so I'd appreciate feedback on this API before anyone start working on it. cc @kenwheeler

Support functions as rule values?

The way you have dynamic styles currently is having a separate function which returns an object of rules, which makes it hard to compose fragments of rules together that may or may not be dynamic.

Could rules themselves be values or functions that return values?

let MyDiv = styled.div({
   color: 'red',
   fontSize: props => props.big ? '20px' : '10px',
})

this way individual rules are agnostic to other ones and don't need to be wrapped in a function in case they don't use props.

thoughts?

Make glamorous faster

We haven't done any benchmarking, but @garetmckinley is going to:

I'm going to benchmark glamorous against styled-components this week, so we will see what the numbers say ๐Ÿ˜Š dont worry, I still love ๐Ÿ’…

So let's find bottlenecks and make them faster. There's definitely some low-hanging fruit from my original implementation that didn't need to be that way. Let's start in the render function which is probably the hottest code path of the codebase.

Anyone wanna try setting up some benchmarking to determine our bottlenecks and start speeding things up? Maybe @developit could give us some pointers...

Make glamorous smaller

Because as @philpl put it:

SC v2 will be 11kb gzip, 32kb raw - although lower with preprocessing. @kentcdodds let the bytes war begin ๐Ÿ˜‚

So here are a few ideas on the top of my head:

  1. A lot of the size comes from the list of html attributes and element tag names. I'm not sure how SC is dealing with this but we may be able to learn from it. We could potentially make a build that skips the element tag names altogether and people could just do: glamorous('div')({/* styles */}) on their own. It's mostly a convenience anyway... But I'm pretty sure I'd rather not do this... Other ideas? Maybe we could generate them at runtime somehow?
  2. We added quite a bit with the ThemeProvider and not everyone needs to support theming. So we could make a build that excludes the ThemeProvider related code ๐Ÿค” Things could get pretty messy though!
  3. Anything else? Someone wanna peruse the code and see where we could shave some bytes?

withTheme() HoC for theming normal components

As discussed with @kwelch in #24 we might want to provide a withTheme() HoC that allows using theming capabilities with non-glamorous components.

import {withTheme} from 'glamorous'

const Hello = ({theme, ...rest}) =>
  <div style={{color: theme.colors.primary}} {...rest} /> 

export default withTheme(Hello)

withTheme() will just receive the context, setup subscription and return the wrapped component with a theme prop.

Am I correct @kwelch ?

Theming

Would you consider theming support as s-c does?
If so, do you need help?

ForwardProps are not being forwarded

  • glamorous version: 3.5.0
  • glamor version: 2.20.24
  • react version: 15.4.2

What you did:
I tried to use glamorous to wrap a third party framework's component.

What happened:
My forwardProps did not get applied to the child of the glamorous component, and I was then able to reproduce the issue in the forwardProps example

Reproduction:

Below is the forwardProps example code.
"Hello worlds" should be rendered but is not:
https://codesandbox.io/s/GZEo8jOyy

Problem description:
forwardProps is not forwarding props

use html-element-attributes

Right now we've got our own list of html-element-attributes. But we should probably rely on another package that will keep itself updated. So it was suggested in #8 that we use https://github.com/wooorm/html-element-attributes from @wooorm

It doesn't have all the svg attributes (maybe that's something @wooorm would be willing to support?). And it also doesn't have the react-specific props so we'll probably want to keep those too. But for some of this we could simplify this file a bit by using that. Pretty much just need a refactor of that file to replace htmlProps with that file's stuff. One thing that shouldForwardProperty accepts is a tagName which is great because it means we can leverage the knowledge of tag-specific props that html-element-attributes has to be more specific about which props to forward.

I think we should probably add some unit tests for that file as well so it's more clear what that module is capable of/responsible for.

If anyone wants to take this on, let us know!

Support custom props

So styled-components v2 was released with a cool new attrs API.

With glamorous, in our examples, we say you can do:

const Password = glamorous.input({})
Password.defaultProps = { type: 'password' }

That works great unless you want the value to be dynamic and derived from props. The example they have is a little unnecessary, but I could see a situation where you'd want to have the props you pass to a wrapped component be mapped to some other value. So I wonder whether folks think this would be useful or just make things more complex.

Option 1: Leave things as they are:

const ValidatedInput = glamorous(({validationType, ...rest}) => {
  let extraProps = {type: validationType}
  if (validationType === 'credit-card') {
    extraProps = {pattern: creditCardPattern}
  }
  return <input {...extraProps} {...rest} />
}, {rootEl: 'input'})({
  /* styles */
})

Option 2: Add an API:

const ValidatedInput = glamorous.input({/* styles */}).props(({validationType}) => {
  if (validationType === 'credit-card') {
    return {pattern: creditCardPattern}
  }
  // validationType could be `email`, `url`, etc.
  return {type: validationType}
})

I value small APIs, but I also value ergonomics. I would love to hear people's perspectives on this. I'll open this up for a vote after we hear what folks have to say about this.

export 'Div' was not found in 'glamorous'

  • glamorous version: ^3.12.0
  • glamor version: ^2.20.24
  • react version: 15.4.1

Relevant code.

// importing documented built-in
import {Div} from 'glamorous'

// class method
render() {
  <Div />
}

What you did:

importing built-in HTML tag as defined in the documentation

What happened:

throws an error and prevents the app from building.
export 'Div was not found in 'glamorous'

Reproduction:

not able to reproduce on codesandbox.io

Problem description:

the code was using the built-in html tags as defined in the docs. when refactoring the same code in a new project, I cam across this error.

Suggested solution:

skimming through this thread:
#42
... it became obvious a simple way to get around this was to define these tags as methods of glamorous.

// before
import {Div} from 'glamorous'

// after
import glamorous from 'glamorous'
const Div = glamorous.div()

Question

Maybe I am dumb, but what's wrong with Fela or Styletron?

Support jsxstyle components

https://github.com/smyte/jsxstyle experts several components. Glamorous exports element components that resemble the API. In addition to those element components, I'd like to also export the jsxstyle components because they have merit and make it more straightforward for people used to that API. We could learn from what glamor did to support this: https://github.com/threepointone/glamor/blob/master/src/jsxstyle.js

I expect this would just add a handful of lines of code...

create a babel plugin to make the displayName a little better

Right now if you do:

const MyDiv = glamorous.div()

Then MyDiv.displayName will be glamorous(div) which is not very helpful in the React DevTools:

screen shot 2017-04-07 at 9 46 12 am

babel-preset-react actually has a babel plugin to set the displayName property when you use React.createClass and I think that we could do the same thing here.

So our plugin could basically transform this:

const MyDiv = glamorous.div()

into this:

const MyDiv = glamorous.div()
MyDiv.displayName = 'MyDiv'

Should be a fairly straightforward plugin. If anyone wants to try this out, but hasn't had experience with babel or ASTs, then this may be helpful. Anyone wanna give it a go?

Allow importing built-in glamorous components

I think it would be awesome to allow something like import { Div, Span } from 'glamorous'. It's not a huge deal to just pull it off below, but I get questions about this and was wondering if there is a possible solution.

It seems that we will need some type of pre-build or babel-transform to accomplish this, I'm not really familiar in this area, but I'm willing to help out wherever I might be able to.

glamorous.path does not render the `d` attribute

  • glamorous version: 3.13.0
  • glamor version: 2.20.24
  • react version: 15.5.4

Relevant code.

See repro.

What you did:

Tried to style a path in an SVG.

What happened:

The d attribute is not rendered.

Reproduction:

https://codesandbox.io/s/zmGG3ZlR5

Problem description:

glamorous.path does not render the d attribute.

Suggested solution:

glamorous.path should render the d attribute.

Improve Server Side Rendering

The styled-components v2 announcement blogpost states:

When you server-side render an app with ๐Ÿ’… styled-components it will automatically only send the critical CSS down to the client.

I'm pretty sure that we don't actually do that right now. As soon as you say:

const Button = glamorous.button({ /* styles */})

Those styles get added to glamor... wait...

jkjk, we totally don't add them to glamor until rendering time. Just verified this with:

import React from 'react'
import ReactDOM from 'react-dom'
import {styleSheet} from 'glamor'
import glamorous from '../'

const Button = glamorous.button({marginLeft: 20})
console.log(styleSheet.inserted)
// -> {}
const x = <Button />
console.log(styleSheet.inserted)
// -> {}
ReactDOM.render(x, document.createElement('div'))
console.log(styleSheet.inserted)
// -> { '140tz9x': true }

So I think we're good. EXCEPT!

We could probably improve the experience a bit. If you look at the Next.js example for server side rendering here there's a bit of boilerplate, and the styled-components blogpost says:

On top of that we support concurrent server-side rendering to avoid blocking your process with every request and we automatically rehydrate your styles in the browser.

And further:

All it takes is four lines of code

Let's see if we can improve this experience a bit taking inspiration (again) from styled-components :)

Make glamorous work out of the box with preact

Original issue: preactjs/preact#653 (comment)

At the moment there are a couple of snags while working with preact:

  1. preact doesn't handle the autoFocus attribute in the same way that react does, and, at the moment, does not declare that autoFocus (it uses autofocus) is a valid prop on html intrinsic elements in its typescript definition. Glamorous, on the other hand, only whitelists autoFocus as a prop to be passed on to the intrinsic element, so it does not pass autofocus on. @kentcdodds suggested using forwardProps, but I'm not sure how to use that in this case just yet and it seems like it'd be a hack.
  2. React is a peer-dependency of glamorous, which means you get a warning if you don't have it installed.
  3. Glamorous requires preact-compat. Ideally it would work w/o it.

Support returning an array of styles to be merged from props callbacks

Problem description:

Sometimes I want to do this:

glamorous.div(({big, square}) => {
  const bigStyles = big ? {
    [desktopMediaQuery]: {
      fontSize: 20
    }
  } : {}

  const squareStyles = !square ? {
    [desktopMediaQuery]: {
      borderRadius: '50%',
    }
  } : {}

  return {...bigStyles, ...squareStyles}
})

But that wont work because Object.assign (or object spread in this case) is shallow, so the last desktopMediaQuery object will entirely override the first one. So I have to workaround this limitation myself with more imperative, less expressive code.

Suggested solution:

I think it'd be cool to be able to do this:

  glamorous.div(({big, square}) => {
    const bigStyles = big ? {
      [desktopMediaQuery]: {
        fontSize: 20
      }
    } : {}

    const squareStyles = !square ? {
      [desktopMediaQuery]: {
        borderRadius: '50%',
      }
    } : {}
-   return {...bigStyles, ...squareStyles}
+   return [bigStyles, squareStyles]
  })

And have glamorous forward both of those items to glamor and have glamor merge them as it does everything else so nicely for us.

I'm going to start working on this now... Because I want it now :)

Built-in rect component doesn't render size/position attributes

  • glamorous version: 3.11.2
  • glamor version: 2.20.24
  • react version: 15.5.4

Relevant code.

const BuiltinComponentRect = glamorous.Rect;
const BuiltinFactoryRect = glamorous.rect({ fill: "blue" });
const CustomRect = glamorous("rect", {
  forwardProps: ["x", "width", "height"]
})({ fill: "orange" });

ReactDOM.render(
  <div>
    <svg width="250" height="50">
      <rect x="0" width="50" height="50" fill="red" />
      <BuiltinComponentRect x="60" width="50" height="50" fill="green" />
      <BuiltinFactoryRect x="110" width="50" height="50" />
      <CustomRect x="170" width="50" height="50" />
    </svg>
  </div>,
  document.getElementById("root")
);

What you did:

N/A

What happened:

In Firefox and Edge, the green (built-in component) and blue (built-in factory-created component) boxes do not render correctly (they have no size) and in Chrome, the blue box doesn't render.

Reproduction:

https://codepen.io/alteredconstants/pen/YVZByv?editors=0010

Problem description:

I could very well be misunderstanding something, but it appears that the x, width, and height props are not being passed on to the underlying <rect> element with the built-in component/component factory. Inspecting the DOM in Chrome, it looks like glamorous.Rect is rendering those props as styles rather than attributes (which appears to be unsupported in Firefox) and the glamorous.rect-generated component simply doesn't render them at all.

Suggested solution:

I haven't used this library much (I like it so far!) but the docs suggest that non-style props on the built-in components should be passed through as attributes (e.g. href on <a>). I'm guessing these size/position ones aren't because they're also style properties? Considering this doesn't currently work on Firefox and Edge, I'd suggest adding those as exceptions for SVG components as they are effectively unusable otherwise.

Or since that might break things for people who only care about Chrome, maybe just a note about this in the docs recommending using the custom component syntax in this case.

require("glamorous").default undefined?

  • glamorous version: 3.11.1
  • glamor version: 2.20.4
  • react version: 15.5.4

What you did:

I'm creating an UI component package written in Typescript.

What happened:

The UI component is written in ES6. Then Typescript compiles ES6 code to ES5. But it throws error when using the package.

Here's the compiled ES5 code:

image

Problem description:

The error says that glamorous.default is undefined

Fix Typescript typings to work with dynamic styles

  • glamorous version: 3.10.0
  • react version: 15.4.2

Currently when we want to use dynamic styles in Typescript:

const MyStyledDiv = glamorous.div(
  {
    margin: 1,
  },
  (props) => ({ // If you are using noImplicitAny rule you get an error:
                // Parameter 'props' implicitely has 'any' type
                // It can be fixed by simple supplying the type
                // like this `(props : { noPadding?: boolean }) => `
    padding: props.noPadding ? 0 : 4,
  })
)

<MyStyledDiv />
<MyStyledDiv noPadding /> // You get error here as well:
                          // Property 'noPadding' does not exist on type 'IntrinsicAttributes & HTMLProps<HTMLDivElement> & { children?: ReactNode; }'

We get these two errors ๐Ÿ˜• (commented in the snippet).

It can be fixed pretty nicely. By making glamorous.div (and all other html element functions) accept optional generic with custom props we solve both errors and get proper intelliSense with all its glory ๐Ÿ˜Ž.

How does the code look with the optional generic:

const MyStyledDiv = glamorous.div<{ noPadding?: boolean }>(
  {
    margin: 1,
  },
  (props) => ({
    padding: props.noPadding ? 0 : 4,
  })
)

<MyStyledDiv />
<MyStyledDiv noPadding />

It is just needed to make a few typings changes in typings/styled-function.d.ts:

export type StaticStyles<Properties> = Partial<Properties>
export type DynamicStyledFunction<Properties, CustomProps> = ( // added CustomProps generic
  props: CustomProps, // changed from `props?: object`
  theme?: object,
) => Partial<Properties>;

type Styles<Properties, CustomProps> = Array<DynamicStyledFunction<Properties, CustomProps> | StaticStyles<Properties>> // added CustomProps generic

...

export interface StyledFunction<Props, Properties> {
  <CustomProps>( // added CustomProps generic
    style1: StaticStyles<Properties>,
    ...styles: Styles<Properties, CustomProps> // added CustomProps generic
  ): GlamorousComponent<Props & CustomProps>; // added CustomProps generic
}

export interface StyledFunction<Props, Properties> {
  <CustomProps>( // added CustomProps generic
    style1: StaticStyles<Properties>,
    style2: StaticStyles<Properties>,
    ...styles: Styles<Properties, CustomProps> // added CustomProps generic
  ): GlamorousComponent<Props & CustomProps>; // added CustomProps generic
}

export interface StyledFunction<Props, Properties> {
  <CustomProps>( // added CustomProps generic
    style1: StaticStyles<Properties>,
    style2: DynamicStyledFunction<Properties, CustomProps>, // added CustomProps generic
    ...styles: Styles<Properties, CustomProps> // added CustomProps generic
  ): GlamorousComponent<Props & CustomProps>; // added CustomProps generic
}

... // the same for the rest

I am ready to make a pull request if you think it is good like this ๐Ÿ™‚.

Add Notes to readme around limitations of typescript support

Problem description:

The current bundled typescript definitions are incomplete and based around the needs of the developers who contributed them.

Whilst this is true of the definitions of many non typescript projects, it could still be a pain point for consumers.

Suggested solution:

It would nice to add a small section to the README with a brief overview of what the definitions do and don't include currently.

I'll likely be able to open a PR in a few days, however if someone is able to work on this before then, that would be great ๐Ÿ‘ .

Regression: GlamorousComponent being a class instead of stateless function causes issue with wrapped inputs

  • glamorous version: 3.6.0

Check this simplified example of my code: https://codesandbox.io/s/L8OYqz1Wv

Since the result of glamorous(Comp) is now a class rather than a function, react now remounts the component on each rerender causing inputs to break. (Just start typing in the example. This used to work before introducing the theming support).

I am aware that the code-example can be rewritten quite easily to make it work, but the form framework I'm using encourages that pattern of the code example.

And finally: Thanks for this awesome library! This actually is the first time I'm feeling like I can stick with a styling solution for a long long time ๐Ÿ˜ƒ

Create a website

I started some work on the glamorous website a while back and haven't had as much time as I would like to actually finish it. Here's the CodeSandbox.

I think that our docs are sufficiently large that a website would be really helpful. I would love it if someone take this over and be in charge of shipping the website.

Localization is important, so I'd like that to be possible. I was playing around with some i18n abstractions and think it's actually pretty good (though it currently requires all translations to be shipped with the JavaScript). For the actual documentation pages, I expect to have them in markdown files in the repo. I'd love to do what the babel-handbook has done to do translations. I think that would be great.

I'm not married to the website that I've worked on. If someone else wants to build something from scratch that'd be great. I think that it'd be cool to put the website in the /site folder. Who wants to help with this?

Passing down `className`?

  • glamorous version: 3.13.3
  • glamor version: 2.20.25
  • react version: 15.5.4

The problem:

To have the styles apply, you have to pass className onto the div from the props. Is there a specific reason this is the case? It seems like boilerplate and I can not find this being documented in the docs.

Relevant code:

Render method of ToggleButtonGroup

  render() {
    return (
      <div value={this.getCurrentSelection()} className={this.props.className}>
        {React.Children.map(this.props.children, (child, i) => (
          <child.type
            // irrelevant props given
          >
            {child.props.children}
          </child.type>
        ))}
      </div>
    )
  }

Styling an instance of ToggleButtonGroup in another component.

const StyledToggleButtonGroup = glamorous(ToggleButtonGroup)({
  backgroundColor: "red",
})

image

The only reason className is on that div is because it is passed down

Document issues with dynamic styled-components

So styled-components has a sweet babel plugin that allows you to do ahead of time compiling of your styled components. This means that you can just compile at dev-time and you don't have to ship the parser. That's pretty sweet because the parser's big and is a bit of a bottleneck. The plugin is even capable of allowing you to continue have dynamic styles like so:

const Button = styled.button`
  /* Adapt the colors based on primary prop */
  background: ${props => props.primary ? 'palevioletred' : 'white'};
  color: ${props => props.primary ? 'white' : 'palevioletred'};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

However, one thing it cannot do for you is allow you to have dynamic parts of your CSS string that would require the parser to parse out. For example:

function verticallySpaceChildren(space) {
  // this stuff requires the parser, but the babel
  // plugin can't get these transpiled, especially
  // if they're in a separate file.
  return `
    & > *:not(:first-child) {
      margin-left: ${space / 2}px;
    }
    & > *:not(:last-child) {
      margin-right: ${space / 2}px;
    }
  `
}

const Container = styled.div`
  display: flex;
  ${verticallySpaceChildren(12)}
`

There are a bunch of similar utilities in styled-components/polished and there's an additional plugin you can install to precompile those as well which is pretty sweet!

Unfortunately, I don't feel like it's worth the effort to write a custom babel plugin that works for all dynamic capabilities when glamorous is more straightforward. But if you commit yourself to not doing this level of dynamic stuff, then feel free to keep using styled-components :)

Create ESLint plugin for CSS in JS?

Great library! From the readme:

There are actually quite a few solutions to the general problem of styling in React. This isn't the place for a full-on comparison of features, but I'm unaware of any which supports all of the features which this library supports.

One thing that styled-components does have is a stylelint processor, which allows you to use stylelint (the css linter) for styles written with styled-components. Which is pretty nice to have.

Just a suggested feature. Think it'd make this library even more complete! (See also this article)

Generate functional class names

First off, thank you for this lib! I've really enjoyed using it. I was wondering if you would be interested in allowing an option to generate functional class names instead of unique class names? Similar to what CXS does. I'd be willing to try out a PR :) just let me know.

Allow passing propsAreStyleOverrides into the glamorous() composer

There are occasions where it would be nice to access the "props as styles" feature, but that is only supported by the built-in components, unless you know where to look.

This can be accomplished by adding propsAreStyleOverrides as a property onto the GlamorousComponent

const MyComponent = glamorous.div({backgroundColor: 'blue'})
MyComponent.propsAreStyleOverrides = true

<MyComponent color="white">Hello World</MyComponent>
// renders: <div />
// with styles {background-color: 'blue', color: 'white'}

When I do this, I can't help but feel that I'm doing something I'm not meant to do; that I'm hacking my way in. It would be great if I could tell the glamorous composer how to configure the factory.

Proposal

Allow passing propsAreStyleOverrides into the glamorous() composer.

const MyComponent = glamorous(div, {propsAreStyleOverrides: true})({backgroundColor: 'blue'})

<MyComponent color="white">Hello World</MyComponent>
// ditto as above

Inspired by robinpowered/glamorous-native#9 (comment)

IE11: Object doesn't support property or method 'assign'

"glamor": "2.20.24",
"glamorous": "3.2.0",
"react": "15.5.3",

IE11 complains about the missing Object.assign even though babel-polyfill are imported the top of the app. The issue is that glamorous.es.js is loaded before babel-polyfill
Using the babel plugin transform-object-assign doesn't help either.

SSR story

Hey Kent!

Thanks for adding to CSS-in-JS fatigue with another worthwhile entry! ๐Ÿ˜œ

It looks really great, and I am looking forward to giving it a try. One question though, have you considered the server side rendering workflow yet?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.