menu

styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress!

Channels
Team

Any component libraries built with styled-components and TypeScript?

January 11, 2019 at 1:15pm

Any component libraries built with styled-components and TypeScript?

January 11, 2019 at 1:15pm

Are any of you aware of an open-source component libraries built with styled-components and TypeScript that we can see?


January 11, 2019 at 2:00pm

You can take a look on my components, xy-grid and image are unsing styled-components and typescript (just start with it) https://github.com/growcss/growcss/tree/next/packages/core

  • reply
  • like

You can take a look on my components, xy-grid and image are unsing styled-components and typescript (just start with it) https://github.com/growcss/growcss/tree/next/packages/core

Very interesting, thanks! How come you have things like the Image breakpoints, or the Grid gutters in local files? Why aren't you using a theme? Also what's the point of your GutterProps interface? It's nice that you are setting the allowed types, but i'd find it a lot more useful if the only allowed values are 'small' or 'medium'(which are the variants of the gutters you've set in https://github.com/growcss/growcss/blob/next/packages/core/xy-grid/src/components/gutters.ts)

  • reply
  • like

I have the breakpoints in local files, because i didnt start to create a theme component :D, is my next step

And the point about the GuttersProps Interface is that you can extend it, if you need gutters for large. You have the option to overwrite the gutterSizes of a grid

  • reply
  • like

Overriding them makes sense, i'd argue though that the interface should only allow you to specify gutter values that you specified for that component. If you've set [these gutter sizes](https://github.com/growcss/growcss/blob/next/packages/core/xy-grid/src/components/gutters.ts) in your library you should only be able to specify small or medium and nothing else when setting the gutter prop (if you decide to add one)

  • reply
  • like

The problem is that the gutter sizes are connected to the breakpoints, if i start with the theme component, i will change this https://github.com/growcss/growcss/blob/next/packages/core/xy-grid/types/index.tsx#L34 to look like the GuttersProps, and without a default object / value anymore

  • reply
  • like

I'm also working through building a component library using styled-components, styled-system and typescript... hasn't be easy so far. The typings for both libraries are pretty complex

  • reply
  • like

Here is a sample of what I've been experimenting with: https://gist.github.com/chiplay/d10435c0962ec62906319e12790104d1

  • reply
  • like

Everything is working pretty great except spreading {...props} into the styled-component, that seems to be the issue.

  • reply
  • like

January 12, 2019 at 6:15pm

I figured out a fix for the {...props} issue, seems to be working great so far. Appreciate any feedback!

  • reply
  • like

January 13, 2019 at 11:25pm

We did the same, with styled-components + styled-system+ typescript: https://github.com/artsy/palette

  • reply
  • like

Its worked out so well! And styled-system in particular -- its reduced our overall complexity / LOC count in our host apps by a mind boggling amount

  • reply
  • like

additionally, lots of these components share really well across our web / react native boundary

  • reply
  • like

and pretty much never have to write css anymore

  • reply
  • like

January 14, 2019 at 8:09am

Where is the children prop's type defined? I only see types inherited from SS.

  • reply
  • like

Its worked out so well! And styled-system in particular -- its reduced our overall complexity / LOC count in our host apps by a mind boggling amount

Can you tell us more about this? How/why did you benefit from building this library?

  • reply
  • like

January 14, 2019 at 4:49pm

Styled system simplifies the whole process of building the component lib since it provides a lot of functional props that you can "mix in" to your components, and each of those functions tap into a theme file. For example:

  • reply
  • like

Here's our <Box> component: Not much logic, but lots of functional mixins from styled-system: https://github.com/artsy/palette/blob/master/src/elements/Box/Box.tsx#L59-L74

And here's our theme, which styled-system natively reads:

https://github.com/artsy/palette/blob/master/src/Theme.tsx

Since these functions are essentially props each of their functions can be accessed at the component props level -- so before when one needed to add space or margin color or something they'd have to create a new component, and add the styles (via styled-components strrings) but now can just do p={2}. It reduces the LOC count considerably and co-locates things with the component where its being used. Seems a little weird initially but then it becomes incredible!

  • reply
  • like

Also, styled-system has a notion of "responsive styles" -- meaning if you define breakpoints in your theme file can do something like this:

<Box p={[10, 20]}>...</Box>
  • reply
  • like

which means at xs, padding is 10, and greater than xs it's 20. This kind of thing applies to all styled-system functions

  • reply
  • like

Check it out https://jxnblk.com/styled-system/ - when first using it i had an "ah hah!" moment similar to when i first used React, and our whole team is digging its simplicity

  • reply
  • like

Related to the typescript part of the q, the types in

/styled-system are extensive, so you get nice intellisense / validation out of the box

Edited
  • reply
  • like

, how do you go about dealing with the conflict of types for htmlElements and styled-system?

for example, lets take a look at `<img />`. here's the interface for images

interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
alt?: string;
crossOrigin?: "anonymous" | "use-credentials" | "";
decoding?: "async" | "auto" | "sync";
height?: number | string;
sizes?: string;
src?: string;
srcSet?: string;
useMap?: string;
width?: number | string;
}

then, your interface for images

export interface BaseImageProps {
/** The url for the image */
src: string
/** Alternate text for image */
alt?: string
/** A11y text label */
ariaLabel?: string
/** Apply additional styles to component */
style?: object
}
export interface ImageProps
extends BaseImageProps,
SpaceProps,
WidthProps,
HeightProps {}

the important part here is the use of WidthProps supplied by styled-system . that is set as the following:

export interface WidthProps<TLength = TLengthStyledSystem> {
/**
* The width utility parses a component's `width` prop and converts it into a CSS width declaration.
*
* - Numbers from 0-1 are converted to percentage widths.
* - Numbers greater than 1 are converted to pixel values.
* - String values are passed as raw CSS values.
* - And arrays are converted to responsive width styles.
*/
width?: ResponsiveValue<CSS.WidthProperty<TLength>>;
}

unfortunately, when trying use your <Image /> component like so:

function test() {
return <Image width={[1, 2]} />
}

we run into this error:

[ts]
Type 'number[]' is not assignable to type 'string | number | (string & Key[]) | (number & Key[])'.
Type 'number[]' is not assignable to type 'number & Key[]'.
Type 'number[]' is not assignable to type 'number'. [2322]
index.d.ts(1469, 9): The expected type comes from property 'width' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps<ClassAttributes<HTMLImageElement> & ImgHTMLAttributes<HTMLImageElement> & ImageProps, any>, any, any>> & Readonly<...> & Readonly<...>'
(JSX attribute) width?: string | number | (string & TLengthStyledSystem[]) | (number & TLengthStyledSystem[])

so, because ImgHTMLAttributes defines the width type, your use of WidthProps does not work, because you're trying to overwrite a previously written type, which to my knowledge, you cannot do.

i've ran into this problem as well, so i'm interested to see if anyone has been able to create a workaround. thanks.

  • reply
  • like
Show more messages