GithubHelp home page GithubHelp logo

styled-system / styled-system Goto Github PK

View Code? Open in Web Editor NEW
7.8K 50.0 501.0 21.01 MB

⬢ Style props for rapid UI development

Home Page: https://styled-system.com

License: MIT License

JavaScript 100.00%
react css-in-js design-systems styled-components typography layout emotion responsive style-props theming

styled-system's Introduction

Styled System

Responsive, theme-based style props for building design systems with React https://styled-system.com

stars Build Status Downloads Version spectrum-badge size MIT License system-ui/theme

npm i styled-system

Features

  • Add style props that hook into your own theme
  • Quickly set responsive font-size, margin, padding, width, and more with props
  • Influenced by constraint-based design system principles
  • Typographic scale
  • Spacing scale for margin and padding
  • Works with any color palette
  • Works with most css-in-js libraries, including styled-components & emotion
  • Used in Rebass, Reflexbox, and the Priceline Design System

"This is honestly my favourite way to build UI components right now party parrot"

Varun Vachhar

"If you haven't seen Styled System before, do yourself a favour and check it out. It's been a huge influence in my thinking on component-oriented styles."

Mark Dalgleish

"The future of css-in-js is going to look something like styled-system with its responsive values."

Kye Hohenberger

"Coming from @tachyons_css, the styled-system utilities from @jxnblk is the missing link I’ve been looking for."

Nathan Young

"If you make websites/apps with React check out Styled System if you haven't already. You will be amazed at how much faster you can build."

David Yeiser

"If you like Tachyons you will love styled-system. If you don't like Tachyons, you will love styled-system."

Adam Morse

"Styled System is one of the best libraries I have ever used."

Miha Sedej

Try It Out

Try the examples on CodeSandbox

Table of Contents

Usage

// Example uses styled-components, but styled-system works with most other css-in-js libraries as well
import styled from 'styled-components'
import { space, layout, typography, color } from 'styled-system'

// Add styled-system functions to your component
const Box = styled.div`
  ${space}
  ${layout}
  ${typography}
  ${color}
`

Each style function exposes its own set of component props that handle styles based on values defined in a theme.

// width: 50%
<Box width={1/2} />

// font-size: 20px (theme.fontSizes[4])
<Box fontSize={4} />

// margin: 16px (theme.space[2])
<Box m={2} />

// padding: 32px (theme.space[3])
<Box p={3} />

// color
<Box color='tomato' />

// color: #333 (theme.colors.gray[0])
<Box color='gray.0' />

// background color
<Box bg='tomato' />

Responsive Style Props

Set responsive width, margin, padding, font-size, and other properties with a shorthand array syntax. Read more

// responsive width
<Box width={[ 1, 1/2, 1/4 ]} />

// responsive font-size
<Box fontSize={[ 2, 3, 4 ]} />

// responsive margin
<Box m={[ 1, 2, 3 ]} />

// responsive padding
<Box p={[ 1, 2, 3 ]} />

To learn more, see the Getting Started guide or read the docs.

Docs


Further Reading

Built with Styled System

Related

MIT License

styled-system's People

Contributors

allforabit avatar braposo avatar broccolini avatar cereallarceny avatar dburles avatar dependabot-preview[bot] avatar dependabot[bot] avatar ericberens avatar fk avatar flybayer avatar gonzalogm avatar gregoralbrecht avatar johno avatar josepot avatar jxnblk avatar keks0r avatar kevinsuttle avatar mathieudoyon avatar mfix22 avatar sapegin avatar selrond avatar shanecav avatar stevenlangbroek avatar stinodes avatar theutz avatar thompsongl avatar timhudson avatar tkh44 avatar trysound avatar willbamford avatar

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

styled-system's Issues

styled-components innerRef compatibility

See https://www.styled-components.com/docs/advanced#refs

const A = styled(Box)``

const B = styled(cleanElement(A))``

const cleanC = cleanElement(A)
const C = styled(cleanC)``
cleanC.propTypes = { ... }
cleanC.styledComponentId = 'cleanElement'

const App = props => (
  <div>
    <A innerRef={node => console.log('A', node)}>A</A>
    <B innerRef={node => console.log('B', node)}>B</B>
    <C innerRef={node => console.log('C', node)}>C</C>
  </div>
)
A =log=> node
B =log=> null
C =log=> node

@jxnblk Would it be ok to add a static styledComponentId prop inside clean-element.js? Or you don't want any code related to third-party libraries inside this one.

Using extras like borderRadius with components

Hi there

Really enjoying using the style functions to unify the look of my site with these! But I'm having a bit of difficulty understanding how the extra props are used with existing components. In addition to importing any of them (i.e. borderRadius) I have included it as a prop in my component (a styled Box using styled-components. But there is no border-radius on my output.

import styled from "styled-components";
import { Box } from "grid-styled";
import { space, borderRadius } from "styled-system";

const PerformanceTime = styled(Box)`
  display: inline-block;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  ${space};
`;

<PerformanceTime p={1} mb={1} borderRadius={1}>10:00pm</PerformanceTime>

I'm obviously missing something simple!
Thanks

v2

The following items need to be written up as issues and tagged with the v2 milestone.

  • convert to ES module syntax
  • remove idx
  • remove legacy responsiveStyle args parsing
  • consolidate style functions into single file
  • consolidate low-level utilities into single file
  • deprecate remove-props
  • use verbose names for flex properties
  • Numbers in breakpoints should convert to pixels
  • update default theme #91
  • add accessor argument to low-level utilities #87 #50
  • Ensure style prop names are unique #89
  • Add alias option to low-level utilities #90
  • Remove boolValue option & boolean props
  • Normalize border utilities api #98
  • subpackages for monorepo
    • clean-element
    • clean-tag
    • system-components
  • rename theme getter util #88
  • update readme docs

For consideration these can be handled as separate non-breaking changes

  • compose function for space & color
  • props combinations utility
  • add support for verbose margin and padding props
  • add more docs w/ live examples (not a breaking change and can be a follow-up task)

Opposite of removeProps.

I created a wrapper component but I get warnings with invalid props. Is there a clean way to pick only the props styled-system uses?

function SeeMore({ title, isVisible, toggleVisibility, children, ...rest }) {
  // warns if something in rest is an invalid dom node.
  return (
    <Box {...rest}>
      <Box onClick={toggleVisibility}>
        {title}
        {isVisible ? <ExpandMoreStyled /> : <ExpandLessStyled />}
      </Box>
      {isVisible &&
      <Box>
        {children}
      </Box>}
    </Box>
  );
}

Add accessor argument to low-level utilities

For properties like width, the utility changes the value provided via props depending on whether the number is above 1. To extract this sort of logic out, the style, responsiveStyle, and pseudoStyle utilities should accept an accessor/getter function to handle this sort of thing.

// example
const getWidth = n => !num(n) || n > 1 ? px(n) : (n * 100) + '%'

const width = responsiveStyle({
  prop: 'width',
  cssProperty: 'width',
  getter: getWidth
})

Support string values in the spacing scale

It would be great if I could put em strings in the spacing scale. For example:

const a = space({
  theme: { space: ['1em', '2em'] },
  m: 1
});
console.log(a); // { margin: NaN }

Right now they're assumed to be numbers so when the value is multiplied by 1 or -1 to follow the rule

Negative values can be used for negative margins

we get NaN.

Maybe we could check the type of the index in the array before we multiply it by a number?

Optional Wrapper Feature to convert units and/or use object based theme

I was tinkering around a bit and wanted to share a possible feature to your package.
Originally by using an array and referencing the size by index i would need to remember what index my base size is located and if I ever change/add to my unit scales, i would have to refactor.

At first, i was wanting to create a wrapper function that would return x units away from the base value of spacing array.
(example space:[item1,item2,baseSpacing,item3,item4], and if i passed in [0,1,2], would push ['baseSpacing units','item3 units','item4 units'] , slapping on the units was first a work around so your internal doesnt reference theme again. But then I realized i also created a solution another issue i was having(wanting to convert your functions response to rem units).

I then realized i could throw away my original mid-referencing function and I can just create a wrapper that doesn't reference the original arrays, i can have it reference an object, so my keys dont change, but i can add more keys if need be, and also throw in an option to return which unit and do the conversion (still assuming all scales are in px)

So my proposal is having a utility function, or separate function that returns different unit. that way we can still have functions reference the theme internally and do conversion rather than do:
Original:
import {spacing} from 'styled-system'
import theme from '../'
import rem from '../'

Separate Import:
import {spacingRem} from 'styled-system'

or Wrappers:
import {spacing,wrapper} from 'styled-system'
styled.box${wrapper(spacing)}

I think wrapper utilities would work the best since you can have a wrapper for all units, and have a wrapper to reference a keyed object instead of an array, which reroutes some internals.

Let me know if any of this is making any since, im fairly new to coding, so if you dont think its worth it, its probably not worth it ha.

Heres my messy sandbox ive been tinkering around with:
Edit StyledSystem Testing

Responsive directional space doesn't work as expected

Another great library, thanks!

I discovered a small issue. Applying responsive directional margins and paddings don't seem to work right. It seems to only apply the responsive padding or margin for the last defined direction, for example:

<MyComponent pt={[1, 2]} pb={[3, 4]} />

The result is that the bottom padding is applied correctly on both breakpoints, but the top padding is only correct on the smaller breakpoint.

Wrong prop type for alignItems

Either prop type should be

{ align: responsive }

Or align-items implementation should be changed to

responsiveStyle('alignItems')

Question: Why em's for breakpoints and not px?

As the title says: "Why em's for breakpoints and not px"

Genuinely curious, and would love to be pointed at a place where this is written up as best practice, as I'm sure you did so for good reason.

Update default theme

  • Use a more common standard for space [ 0, 4, 8, 16, 32, 64, 128, 256, 512 ]
  • Use string em unit values for breakpoints [ '40em', '52em', '64em' ]

Missing propTypes.borderColor

The propTypes export doesn't define borderColor, so the cleanElement HOC doesn't strip this prop and it's passed down to the styled element.

using `...typography.propTypes` throws an error

Basic example:

import { space, fontSize, color, typography } from 'styled-system'
import Tag from 'clean-tag'

const StyledH1 = styled(Tag.h1)`
	${space};
	${fontSize};
	${color};
	${typography};
`
export const H1 = ({ children, ...rest }) => (
	<StyledH1 {...rest}>
		{children}
	</StyledH1>
)

then adding propTypes:

H1.propTypes = {
	children: PropTypes.node.isRequired,
	...space.propTypes,
	...fontSize.propTypes,
	...color.propTypes
}

everything's fine, but when ...typography.propTypes is added

H1.propTypes = {
	children: PropTypes.node.isRequired,
	...space.propTypes,
	...fontSize.propTypes,
	...color.propTypes,

	// This causes TypeError
	...typography.propTypes
}

TypeError is thrown:

image

Duplicate style props

Great work on this package, Brent!

I've been running into an issue where I want both textAlign and alignItems style props. But the problem is both use align for the prop.

I think it'd be great to impose uniqueness on the style props as a fundamental principle.

Thoughts?

Not an issue but a kudos....

styled-system, and specifically responsiveStyle, has made a significant change to how I write my styled components. The more I use it, the more I see my components styling changing and becoming more clean.

Excellent job and my thanks for this package!

Support styled-jss

styled-jss is near to have support for function rules in this PR, the added docs here explain how to add multiple function rules, like the great ones you offer in this wonderful lib... is it posible to support their theming api?... In my case I'm using material-ui v1 and they select react-jss as their CSSinJS engine of choice for performance reasons (and other reasons) they explain here and here. It would be awesome to be able to use the same api as styled-components and have this utility methods playing nice together.

Container Queries?

Trying to chart out a path of styling that allows me to "learn once, write anywhere" and zero-ing in on this library for theming.

Would I be able to combine styled-system with react-component-queries?

separate static and dynamic styles, to improve performance

implement hoc in styled-system:

import {
  arrayOf,
  oneOfType,
  number,
  string
} from 'prop-types'
import {
  space,
  width,
  fontSize,
  color
} from './index'
import tag from '../tag'                  // from tag-hoc
import blacklist from '../base/blacklist'  // from rebass
import theme from '../base/theme'         // from rebass
import props from './props'

const prop = oneOfType([
  number,
  string,
  arrayOf(oneOfType([
    number,
    string
  ]))
])

const propMap = Object.keys(props)
  .reduce((acc, p) => {
    const file = props[p]
    if (!acc[file]) acc[file] = []
    return { 
      ...acc,
      [file]: [ ...acc[file], p ],
    }
  }, {})

const resolve = obj => (obj && obj.__esModule ? obj.default : obj)

const withStyle = options => Component => {
  const staticStyle = Object.keys(options)
    .filter(key => typeof options[key] !== 'function')
    .reduce((acc, key) => {
      const func = resolve(require(`./${props[key]}.js`))
      return {
        ...acc,
        ...func({ [key]: options[key], theme })
      }
    }, {})

  const dynamicStyle = Object.keys(options)
    .filter(key => typeof options[key] === 'function')
    .reduce((acc, key) => (
      [
        ...acc,
        options[key]
      ]
    ), [])
    
  const dynamicPropTypes = Object.keys(options)
    .filter(key => typeof options[key] === 'function')
    .reduce((acc, key) => (
      {
        ...acc,
        ...propMap[key].reduce((a, p) => ({...a, [p]: prop}), {})
      }
    ), {})

  const Base = styled(Component)([], ...dynamicStyle)
  Base.propTypes = dynamicPropTypes

  // Clean this up after styled-components removes whitelisting
  return styled(Base)([], staticStyle)
}

const baseOptions = {
  space,
  width,
  fontSize,
  color,
};

const Tag = tag(blacklist)

function compose(...funcs) {
  if (funcs.length === 0) return arg => arg
  if (funcs.length === 1) return funcs[0]
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

const hoc = (options = baseOptions) => compose(
  withStyle(options),
  Tag
)

export default hoc

props.js :

export default {
  'm': 'space',
  'mt': 'space',
  'mr': 'space',
  'mb': 'space',
  'ml': 'space',
  'mx': 'space',
  'my': 'space',
  'p': 'space',
  'pt': 'space',
  'pr': 'space',
  'pb': 'space',
  'pl': 'space',
  'px': 'space',
  'py': 'space',

  'w': 'width',
  'width': 'width',

  'color': 'color',
  'bg': 'color',
  ...

usage:

import { hoc as withSystemStyled, hover } from 'styled-system'

const BaseFixedBar = withSystemStyled({
  // following options run once in initialization
  width: '100%',
  px: 2,
  py: 0,
  bg: 'blue6',
  color: 'white',

  // following props run in every instance
  hover,
  ...
})('div');

const FixedBar = styled(BaseFixedBar)`
  position: fixed;
  left: 0px;
  top: 0px;
  z-index: 10;
  height: 48px;
  display: flex;
  align-items: stretch;
`

<FixedBar hover={{backgroundColor: "blue8"}}>
 ...
</FixedBar>

benefit:
improve performance, in SSR specially

System-Components BEM Composition?

I'm trying to create some components and have a Block.Element structure,
In the example attached I have

const Grid = system(
  'width',
  'space',
  'fontSize',
  'color',
  'size',
  'overflow',
  'gridContainer',
  { display: 'grid' }
)

export const GridItem = system('size', 'gridItems')

export default Grid

But want to export GridItem attached to grid like:

const Grid = system(
  'width',
  'space',
  'fontSize',
  'color',
  'size',
  'overflow',
  'gridContainer',
  { display: 'grid' }
)

Grid.Item = system('size', 'gridItems')

export default Grid

Is that possible or do we lose that capability passing through system?

Edit cssgrid-styled

Applying spacing to properties other than margin and padding

When I started playing around with styled-system, one of the first things I wanted to do was apply spacing to properties other than margin and padding. There are loads of properties this might be useful for: top, right, bottom, left, grid-gap, text-indent, etc.

At first I thought I might be able to do this with responsiveStyle, but I don't think that's the case, and I couldn't find anything else included to do this.

I hacked something together based on responsiveStyle, providing an API like this:

const FixedTR = styled.div`
  position: fixed;
  ${spaceStyle('pos', space => `
    top: ${space};
    right: ${space};
  `, 1)}
`

const App = () => (
  <FixedTR pos={[ 2, 3 ]} />
)

spaceStyle takes three arguments:

  1. The property to read the scale from.
  2. The function the space value is passed into, used to create the CSS rule/s at each breakpoint.
  3. The default scale value.

It seems to work, but I haven't done a lot with it.

My question is; am I totally missing the point of styled-system? Is there a reason it doesn't do this already? It's possible this just isn't the intended use 😅. Or maybe there is a glaringly obvious way to do this, and I just didn't realise!

Example.

The source for spaceStyle:

import { util, constants } from 'styled-system'

const {
  get,
  arr,
  px,
  neg,
  num,
  breaks,
  media
} = util

const spaceStyle = (key, fn, defaultVal) => props => {
  const bp = breaks(props)
  const sc = get(props, 'theme.space', constants.space)

  const val = typeof props[key] !== 'undefined'
    ? props[key]
    : defaultVal

  return arr(val)
    .map(mx(sc))
    .map(fn)
    .map(media(bp))
    .reduce(merge, '')
}

export default spaceStyle

const mx = scale => n => {
  if (!num(n)) {
    return n
  }

  const value = scale[Math.abs(n)] || Math.abs(n)
  if (!num(value)) {
    return value
  }

  return px(value * (neg(n) ? -1 : 1))
}

const merge = (reduced, css) =>
  typeof css === 'string'
    ? reduced + css
    : merge(reduced, ` ${Object.keys(css)[0]} { ${Object.values(css)[0]} }`)

Thanks!

[Doc] How to access theme values

Hey,

I'm seeing that is possible access to theming values, such as:

import { theme } from 'styled-system'
theme('color.white') // => '#fff'

how do that, for example, for array elements?

I'm trying different approach but looks it doesn't works

import { theme } from 'styled-system'
theme('breakpoints.1') // => nope?
theme('breakpoints[1]') // => nope?

why is null prepended onto the overriden breadpoints

On line 11 of util.js null is appended onto the breakpoints that are coming from the theme.

If I have breakpoints like this:

[
  '0em',
  '36em',
  '48em',
  '62em',
  '75em'
]

Calling width results in my last breakpoint is omitted.

Would you be open to a PR to remove null or am I missing something?

Add a way to transform reponsiveStyle

I'm trying to add max-height prop, with a similar behavior than width:

const cardHeight = responsiveStyle({
  prop: 'maxHeight',
  cssProperty: 'maxHeight'
})

The problem with this factory is that is not handling different units (pixels, rem, %, ...)

I saw how you do it at src/width.

A simple way to reach this is providing a transformation method as function:

const cardHeight = responsiveStyle({
  prop: 'maxHeight',
  cssProperty: 'maxHeight',
  transform: n => !num(n) || n > 1 ? px(n) : (n * 100) + '%'
})

What do you think?

`defaultProps` are not respected

Might be missing something here, but when upgrading to 2.1 I noticed that components with default props were not actually styled correctly.

For example, a component like

import { space } from 'styled-system'

const Button = styled.button`
  ${space}
`

Button.defaultProps = {
  p: 1
}

does not have a default padding of 1 applied. It only works if you explicitly pass in the prop, like <Button p={1} />.

fontSize prop renders to font-size attribute

When using ${fontSize} function in my custom component, such as

<H1 fontSize="2em">
	Something...
</H1>

React apparently treats is as HTML attribute and renders it as font-size on the respective tag.

<h1 font-size="2em">
	Something...
</h1>

What can be done to override / circumvent this behavior

Proposal to add flow-type definitions to flow-typed

I am using following flow-types in my project, can someone help me put them to flow-typed? I do not have experience with adding flow-typed definitions for modules.

/**
 * Once filled out, we encourage you to share your work with the
 * community by sending a pull request to:
 * https://github.com/flowtype/flow-typed
 */

declare module 'styled-system' {
  declare export type NumberOrString = number | string;

  declare export type Responsive = NumberOrString | Array<NumberOrString>;

  declare export type ResponsiveBoolean = boolean | Array<boolean>;

  declare export type Width = {
    /** width */
    width?: Responsive,
    /** width */
    w?: Responsive,
  };

  declare export type Space = {
    /** margin */
    m?: Responsive,
    /** margin-top */
    mt?: Responsive,
    /** margin-right */
    mr?: Responsive,
    /** margin-bottom */
    mb?: Responsive,
    /** margin-left */
    ml?: Responsive,
    /** margin-x */
    mx?: Responsive,
    /** margin-y */
    my?: Responsive,
    /** padding */
    p?: Responsive,
    /** padding-top */
    pt?: Responsive,
    /** padding-right */
    pr?: Responsive,
    /** padding-bottom */
    pb?: Responsive,
    /** padding-left */
    pl?: Responsive,
    /** padding-x */
    px?: Responsive,
    /** padding-y */
    py?: Responsive,
  };

  declare export type FontSize = {
    /** fontSize */
    fontSize?: Responsive,
    /** fontSize */
    f?: Responsive,
  };

  declare export type Color = {
    color?: Responsive,
    /** background */
    bg?: Responsive,
  };

  declare export type TextAlign = {
    align?: Responsive,
  };

  declare export type FontWeight = {
    fontWeight?: NumberOrString,
  };

  declare export type LineHeight = {
    lineHeight?: NumberOrString,
  };

  declare export type AlignItems = {
    align?: Responsive,
  };

  declare export type JustifyContent = {
    justify?: Responsive,
  };

  declare export type FlexWrap = {
    wrap?: ResponsiveBoolean,
  };

  declare export type FlexDirection = {
    flexDirection?: Responsive,
  };

  declare export type Flex = {
    flex?: Responsive,
  };

  declare export type AlignSelf = {
    alignSelf?: Responsive,
  };

  declare export type MaxWidth = {
    maxWidth?: NumberOrString,
  };

  declare export type BorderRadius = {
    borderRadius?: NumberOrString,
  };

  declare export type BorderWidth = {
    borderWidth?: NumberOrString,
    borderTop?: boolean,
    borderRight?: boolean,
    borderBottom?: boolean,
    borderLeft?: boolean,
  };

  declare export type BorderColor = {
    borderColor?: string,
  };

  declare export type BoxShadow = {
    boxShadow?: NumberOrString,
  };

  declare export type Hover = {
    hover?: Object,
  };

  declare export type Focus = {
    focus?: Object,
  };

  declare export type Active = {
    active?: Object,
  };

  declare export type Disabled = {
    disabledStyle?: Object,
  };

  // custom
  declare export type Order = {
    order?: Responsive,
  };

  declare export type Props =
    Width &
    Space &
    FontSize &
    Color &
    TextAlign &
    FontWeight &
    LineHeight &
    AlignItems &
    JustifyContent &
    FlexWrap &
    FlexDirection &
    Flex &
    AlignSelf &
    MaxWidth &
    BorderRadius &
    BorderWidth &
    BorderColor &
    BoxShadow &
    Hover &
    Focus &
    Active &
    Disabled;
}

declare module 'grid-styled' {
  declare export type Is = {is?: React.ElementType};

  declare export type BoxProps = Is &
    Width &
    Space &
    FontSize &
    Color &
    Flex &
    Order;

  declare export type FlexProps = BoxProps &
    FlexWrap &
    FlexDirection &
    AlignItems &
    JustifyContent;
}

Adding additional props to styled-system via theme?

Hello, big fan of your work. Thanks for doing OSS!

In this library, you currently allow the usage of responsiveStyles to add additional props for use with the styled-system api.

I am curious what you think about adding the ability to add props to styled-system through styled-components ThemeProvider that you wrap here.

So, if you wanted another attribute available on all components using styled-system... this could be added via the theme.

<ThemeProvider theme={{
    'styled-system-props': {
        'flex-direction': 'direction'
    }
}}>...</ThemeProvider>

If you wanted to go more complicated in the theme, you could allow distinguishing which props to add by component.

<ThemeProvider theme={{
    'styled-system-props': {
          Flex: {
            'flex-direction': 'direction'
          }
    }
}}>...</ThemeProvider>

I think it may be nice to use the responsive api provided by styled-system w/o wrapping a bunch of Rebass (or other styled-system) components w/ styled() and adding responsiveStyles to them.

There may be a good reason not to do this... but if you think it makes sense, I'd be happy to work on a PR.

Please rename prop-types to something else (please read)

I understand that this has come up before and it was dealt with in a PR. However there is still and issue. Webpack has a bug (that I'm trying to get tracked down) where the resolution graph gets messed up and results in prop-types trying to require itself.

Here's a gist of what I'm seeing: https://gist.github.com/zentuit/af24021fa3d95b340413587c4984432e

React's prop-types is moduleId 48 and styled-system's prop-types is moduleId 528. Instead of

var _propTypes = __webpack_require__(48);

I'm getting

var _propTypes = __webpack_require__(528);

Flex basis

Great library to start with!

Just curious, is it possible to be able to have the width be flex-basis instead of width? Or anything like that?

Thanks

Typescript support for styled-system

Hi @jxnblk, do you have any plan for typescript support ?

I use styled-system across projects at work and we use typescripts so we need to additional module declaration for styled-system. If you are planning to have typescript included as part of styled-system then I am more than happy to contribute.

Docs on using responsiveStyle with boolean values

I have been typing to make sure of the responsiveStyle helper that ships with styled-system. That said, I'm trying to use it for a prop that is simply a true/false boolean, and needs change multiple properties when it is true.

Basically, I have a component that I want to switch between a mobile look and a desktop look, but delegate the breakpoint switching to styled-system.

I see that there is an argument on responsiveStyle for "boolValue", but it is not documented on exactly how it works.

Here is the way I am declaring my prop:

<LocationSelector width={350} fullWidth={[true, false]} />

And here is how I have implemented style styles:

export default styled.div`
  width: ${props => `${props.width}px`};
  ${responsiveStyle('width', 'fullWidth', '100%')};
  position: relative;
  z-index: 2;
`

export const StyledLSButton = styled.div`
  display: block;
  cursor: pointer;
  outline: none;
  border: none;
  border-bottom: 1px solid ${props => props.theme.lightMedGrey};
  ${responsiveStyle('margin', 'fullWidth', '0 15px')};
  padding: 0;
  height: 60px;
  background-color: transparent;
  position: relative;
  z-index: 4;
`

export const StyledLSOptions = styled.div`
  opacity: ${props => (props.open ? 1 : 0)};
  pointer-events: ${props => (props.open ? 'auto' : 'none')};
  transition: opacity 0.3s;
  background-color: white;
  top: -15px;
  box-sizing: border-box;
  left: -15px;
  right: -15px;
  ${responsiveStyle('width', 'fullWidth', '100%')};
  ${responsiveStyle('box-sizing', 'fullWidth', 'border-box')};
  ${responsiveStyle('left', 'fullWidth', '0')};
  ${responsiveStyle('right', 'fullWidth', '0')};
  padding: 85px 15px 15px;
  position: absolute;
  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
  z-index: 3;
`

If I don't use an array for fullWidth, and I just toggle it between <LocationSelector width={350} fullWidth /> and <LocationSelector width={350} /> it works as expected, but not when I pass an array of booleans.

Using styled-system with SSR frameworks like Next.js

When using styled-system via styled-components within Next.js (or Nuxt.js), which have server-side rendering by default, the css styling of NPMs (such as styled-system) isn't applied.

Is there a method to easily enable this?

Support for React Native?

Encountering the following error when trying to import styled-system in a project utilizing styled-components/native:

screen shot 2017-08-05 at 4 09 49 pm

Is this a known issue? I didn't see any mention of RN support, and didn't know if you were planning on supporting it or not. Let me know if there's any other info you'd like to see.

Rename theme getter

Since theme is usually used to reference the theme object being passed to a ThemeProvider, the system.theme utility should have a more explicit name.

Some ideas:

  • themeGet
  • themeValue

Use styled functions in complexStyle

I've been finding complexStyle to be quite useful for a few use cases, like button sizing. However, I'm wondering if it might be nice to provide styled function shorthand/usage.

Currently something like this doesn't work:

const buttonSizes = {
  small: {
    py: 2,
    px: 3,
    fontSize: 0,
  },
  normal: {
    py: 3,
    px: 4,
    fontSize: 1
  },
  large: {
    py: 4,
    px: 5,
   fontSize: 2
  }
}

Of course, we can work around it by grabbing from our other objects in theme.js and manually calling util.px or hardcoding values:

import { util } from 'styled-system'

const buttonSizes = {
  small: {
    padding: [space[2], space[3]].map(util.px).join(' '),
    fontSize: '12px'
   }
  // ...
}

Though, to me, this feels a little clunky. Would it be more ergonomic to pass through styled functions, or perhaps optionally pass them in?

import {
  complexStyle,
  fontSize,
  space
} from 'styled-system'

const size = complexStyle({
  prop: 'size',
  key: 'buttonSizes',
  // Pass in functions to transform properties
  systems: [fontSize, space]
})

Another option might be piping:

import {
  complexStyle,
  fontSize,
  space,
  util
} from 'styled-system'

const size = complexStyle({
  prop: 'size',
  key: 'buttonSizes',
  // Pass in functions to transform properties
  systems: [fontSize, space]
})

export default styled.button`
  ${util.pipe(size, fontSize, space)}
`

'color' prop doesn't get filtered out

// Box.js
import React from 'react'
import styled from 'react-emotion'
import { space, width, fontSize, color } from 'styled-system'

const Box = styled('div')`
  ${space};
  ${width};
  ${fontSize};
  ${color};
`;

export default Box

// App.js
<Box color="red" p={12}>Hello</Box>

Then, when I check markup in chrome dev tools, I see

<div color="red">Hello</div>

styled-system 1.0.0
react 16.0.0

Decouple sytled-system from glamorous and styled-components

Hi and thanks for this library!

I've made a (quick and dirty) fork of grid-styled that I've named grid-styletr. It has the exact same API as grid-styled but it's built on top of styletron-react rather than styled-components. Therefore, my fork also depends on styled-system.

I'm using grid-styletr in a pretty big project and so far it's working great. The only "problem" that I have is that I'm getting warnings about an unmet peer dependency:

warning "[email protected]" has unmet peer dependency "glamor@>=2"

That's because styled-system has a dependency on glamorous and glamorous has a peer-dependency on glamor.

Styled-system is a great library. The fact that it can be used from glamour, styled-components, styletron and probably many other css-in-js libraries shows that styled-system has a great API. That's why I think that it should be completely decoupled from any css-in-js library.

I think that the "Box" and the hoc of both glamorous and styled-components don't belong to styled-system. Those are nice helpers that should be implemented from outside of styled-system, so that styled-system can stay completely decoupled from the different css-in-js libraries that can leverage it.

UPDATE:

I was working on a PR for removing these dependencies and then I realized what the issue is: those helpers are only used from inside the "docs" (makes sense). So I guess that the solution is to have those dependencies as part of the dev-dependencies and the helpers declared inside the "docs" folder (no need for those helpers to be part of "dist"). That's pretty much what #10 does. 😄

Responsive on Desktop but not Mobile

Hi, i've been been noticing something as i've been working with this excellent system. The views are responsive work great but only on a desktop display, not on mobile. When I inspect via dev tools and on my own device I'm only getting the desktop view and not the view associated with corresponding breakpoints. This might totally be a error on my end but i'm not sure how to proceed

Would really appreciate any feedback on how to solve this problem. Thanks again for all this amazing work, these libraries are really useful for spinning up layouts quickly!

https://jm-site-react-ondibdnarc.now.sh/

https://github.com/jay-manday/jm-site-react

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.