Repository: styled-system/styled-system (js)

Issue:
All properties from parent category get included when applying an individual prop
I _think_ I've discovered a bug! 

I noticed while working on Primer Components that it seems that all props that exist in a category get included when trying to include just one prop from that category.

For example, I've got some custom categories in Primer Components, one of them being `LAYOUT`:

```
export const LAYOUT = compose(
  styledSystem.width,
  styledSystem.height,
  styledSystem.minWidth,
  styledSystem.minHeight,
  styledSystem.maxWidth,
  styledSystem.maxHeight,
  styledSystem.overflow,
  styledSystem.verticalAlign
)
```

Note that `display` is purposefully excluded from `LAYOUT` because I've already included it in `COMMON`, a different custom category that I've made.

I noticed in my snapshots for our `Box` component that the `display` prop is implemented twice. I confirmed that this was happening by removing `COMMON` from my `Box` component (which previously had both `COMMON` and `LAYOUT`) and seeing if `Box` still gets the `display` prop (from `LAYOUT`) and it does.

Further, I tested out this:

```
export const LAYOUT = compose(
  styledSystem.width,
  styledSystem.height
)

``` 

and confirmed that a component importing the `LAYOUT` group of props is still able to use all the other props in the `layout` category in styled system, even though I've only included `width` and `height`. 

I also tested renaming my custom group of props from `LAYOUT` to `ASDFG` to double check that this wasn't happening because of a naming clash, and confirmed that this still happens with a totally random name.


Pull request:
Update API to allow for single-prop functions from categories
- Adds keys to each category to support using a function for a single property only, e.g. `layout.width` only picks up values from the `width` prop and ignores other `layout` props
- Updates v4 shims to closer reflect behavior from v4

Fixes #580 
Related #562 

Patch:
diff --git a/docs/package.json b/docs/package.json
index d037619..c3405ca 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -13,9 +13,9 @@
     "@mdx-js/mdx": "^1.0.19",
     "@mdx-js/react": "^1.0.16",
     "@styled-system/babel-plugin": "0.0.20",
-    "@styled-system/css": "^5.0.0-7",
+    "@styled-system/css": "^5.0.11",
     "@styled-system/edit": "5.0.5",
-    "@styled-system/should-forward-prop": "5.0.5",
+    "@styled-system/should-forward-prop": "5.0.10",
     "gatsby": "^2.4.6",
     "gatsby-plugin-emotion": "^4.0.6",
     "gatsby-plugin-google-analytics": "^2.0.20",
diff --git a/packages/core/src/index.js b/packages/core/src/index.js
index c146eb1..e4b8152 100644
--- a/packages/core/src/index.js
+++ b/packages/core/src/index.js
@@ -67,6 +67,14 @@ export const createParser = config => {
   parse.config = config
   parse.propNames = Object.keys(config)
   parse.cache = cache
+
+  const keys = Object.keys(config).filter(k => k !== 'config')
+  if (keys.length > 1) {
+    keys.forEach(key => {
+      parse[key] = createParser({ [key]: config[key] })
+    })
+  }
+
   return parse
 }
 
diff --git a/packages/edit/package.json b/packages/edit/package.json
index b5b473d..79fdbe3 100644
--- a/packages/edit/package.json
+++ b/packages/edit/package.json
@@ -3,7 +3,6 @@
   "version": "5.0.5",
   "description": "",
   "main": "dist/index.js",
-  "module": "dist/index.esm.js",
   "keywords": [],
   "author": "Brent Jackson <jxnblk@gmail.com>",
   "license": "MIT",
diff --git a/packages/styled-system/src/index.js b/packages/styled-system/src/index.js
index 903049a..68632a6 100644
--- a/packages/styled-system/src/index.js
+++ b/packages/styled-system/src/index.js
@@ -1,4 +1,13 @@
 import { createStyleFunction, createParser } from '@styled-system/core'
+// v4 api shims
+import layout from '@styled-system/layout'
+import color from '@styled-system/color'
+import typography from '@styled-system/typography'
+import flexbox from '@styled-system/flexbox'
+import grid from '@styled-system/grid'
+import border from '@styled-system/border'
+import background from '@styled-system/background'
+import position from '@styled-system/position'
 
 export {
   get,
@@ -27,82 +36,152 @@ export {
   colorStyle
 } from '@styled-system/variant'
 
-// v4 api shims
-export {
-  default as width,
-  default as height,
-  default as minWidth,
-  default as minHeight,
-  default as maxWidth,
-  default as maxHeight,
-  default as size,
-  default as verticalAlign,
-  default as display,
-  default as overflow,
-} from '@styled-system/layout'
-export { default as opacity } from '@styled-system/color'
-export {
-  default as fontSize,
-  default as fontFamily,
-  default as fontWeight,
-  default as lineHeight,
-  default as textAlign,
-  default as fontStyle,
-  default as letterSpacing,
-} from '@styled-system/typography'
-export {
-  default as alignItems,
-  default as alignContent,
-  default as justifyItems,
-  default as justifyContent,
-  default as flexWrap,
-  default as flexDirection,
-  default as flex,
-  default as flexGrow,
-  default as flexShrink,
-  default as flexBasis,
-  default as justifySelf,
-  default as alignSelf,
-  default as order,
-} from '@styled-system/flexbox'
-export {
-  default as gridGap,
-  default as gridColumnGap,
-  default as gridRowGap,
-  default as gridColumn,
-  default as gridRow,
-  default as gridAutoFlow,
-  default as gridAutoColumns,
-  default as gridAutoRows,
-  default as gridTemplateColumns,
-  default as gridTemplateRows,
-  default as gridTemplateAreas,
-  default as gridArea,
-} from '@styled-system/grid'
-export {
-  default as borderWidth,
-  default as borderStyle,
-  default as borderColor,
-  default as borderTop,
-  default as borderRight,
-  default as borderBottom,
-  default as borderLeft,
-  default as borderRadius,
-  default as borders,
-} from '@styled-system/border'
-export {
-  default as backgroundImage,
-  default as backgroundSize,
-  default as backgroundPosition,
-  default as backgroundRepeat,
-} from '@styled-system/background'
+const {
+  width,
+  height,
+  minWidth,
+  minHeight,
+  maxWidth,
+  maxHeight,
+  size,
+  verticalAlign,
+  display,
+  overflow,
+} = layout
+const { opacity } = color
+const {
+  fontSize,
+  fontFamily,
+  fontWeight,
+  lineHeight,
+  textAlign,
+  fontStyle,
+  letterSpacing,
+} = typography
+
+const {
+  alignItems,
+  alignContent,
+  justifyItems,
+  justifyContent,
+  flexWrap,
+  flexDirection,
+  flex,
+  flexGrow,
+  flexShrink,
+  flexBasis,
+  justifySelf,
+  alignSelf,
+  order,
+} = flexbox
+const {
+  gridGap,
+  gridColumnGap,
+  gridRowGap,
+  gridColumn,
+  gridRow,
+  gridAutoFlow,
+  gridAutoColumns,
+  gridAutoRows,
+  gridTemplateColumns,
+  gridTemplateRows,
+  gridTemplateAreas,
+  gridArea,
+} = grid
+const {
+  borderWidth,
+  borderStyle,
+  borderColor,
+  borderTop,
+  borderRight,
+  borderBottom,
+  borderLeft,
+  borderRadius,
+} = border
+const {
+  backgroundImage,
+  backgroundSize,
+  backgroundPosition,
+  backgroundRepeat,
+} = background
+const {
+  zIndex,
+  top,
+  right,
+  bottom,
+  left,
+} = position
+
+export { default as borders } from '@styled-system/border'
 export {
-  default as zIndex,
-  default as top,
-  default as right,
-  default as bottom,
-  default as left,
-} from '@styled-system/position'
+  width,
+  height,
+  minWidth,
+  minHeight,
+  maxWidth,
+  maxHeight,
+  size,
+  verticalAlign,
+  display,
+  overflow,
+  // color
+  opacity,
+  // typography
+  fontSize,
+  fontFamily,
+  fontWeight,
+  lineHeight,
+  textAlign,
+  fontStyle,
+  letterSpacing,
+  // flexbox
+  alignItems,
+  alignContent,
+  justifyItems,
+  justifyContent,
+  flexWrap,
+  flexDirection,
+  flex,
+  flexGrow,
+  flexShrink,
+  flexBasis,
+  justifySelf,
+  alignSelf,
+  order,
+  // grid
+  gridGap,
+  gridColumnGap,
+  gridRowGap,
+  gridColumn,
+  gridRow,
+  gridAutoFlow,
+  gridAutoColumns,
+  gridAutoRows,
+  gridTemplateColumns,
+  gridTemplateRows,
+  gridTemplateAreas,
+  gridArea,
+  // border
+  borderWidth,
+  borderStyle,
+  borderColor,
+  borderTop,
+  borderRight,
+  borderBottom,
+  borderLeft,
+  borderRadius,
+  // background
+  backgroundImage,
+  backgroundSize,
+  backgroundPosition,
+  backgroundRepeat,
+  // position
+  zIndex,
+  top,
+  right,
+  bottom,
+  left,
+}
 
 // v4 style API shim
 export const style = ({
diff --git a/yarn.lock b/yarn.lock
index 0b1b0cb..3964398 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2228,15 +2228,6 @@
     "@emotion/core" "^10.0.10"
     "@styled-system/css" "^2.0.0"
 
-"@styled-system/should-forward-prop@5.0.5":
-  version "5.0.5"
-  resolved "https://registry.yarnpkg.com/@styled-system/should-forward-prop/-/should-forward-prop-5.0.5.tgz#79a96bd77407176db591c63e8e3286e5d5a23b00"
-  integrity sha512-xwJAZIn26Zz/1P3Fk9tFaYheF1k5+7+OAmUAnT7dYpyoq/rdnUQ8IvHbWr5L/tFkqm0+6ScT1dCkbnADmMimYA==
-  dependencies:
-    "@emotion/is-prop-valid" "^0.7.3"
-    "@emotion/memoize" "^0.7.1"
-    styled-system "^5.0.5"
-
 "@svgr/babel-plugin-add-jsx-attribute@^4.2.0":
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1"


Test patch:
diff --git a/packages/core/test/system.js b/packages/core/test/system.js
index 0fdbb12..908b5af 100644
--- a/packages/core/test/system.js
+++ b/packages/core/test/system.js
@@ -179,6 +179,18 @@ test('skips null values in arrays', () => {
   })
 })
 
+test('includes single property functions', () => {
+  const parser = system({
+    color: true,
+    backgroundColor: true,
+    width: true,
+  })
+  const a = parser.color({ color: 'tomato', backgroundColor: 'nope'  })
+  const b = parser.width({ width: '100%', color: 'tomato', backgroundColor: 'nope'  })
+  expect(a).toEqual({ color: 'tomato' })
+  expect(b).toEqual({ width: '100%' })
+})
+
 test('parser configs can be composed manually', () => {
   const color = system({ color: true, backgroundColor: true })
   const layout = system({ width: true, height: true })
@@ -193,4 +205,4 @@ test('parser configs can be composed manually', () => {
     backgroundColor: 'black',
     width: '100%',
   })
-})
+})
\ No newline at end of file
diff --git a/packages/styled-system/test/shim.js b/packages/styled-system/test/shim.js
index d35b19a..8053fd2 100644
--- a/packages/styled-system/test/shim.js
+++ b/packages/styled-system/test/shim.js
@@ -1,4 +1,4 @@
-import { style } from '../src'
+import { style, width as systemWidth } from '../src'
 
 const width = style({
   prop: 'width',
@@ -107,3 +107,12 @@ test('array values longer than breakpoints does not reset returned style object'
   })
   expect(a).toEqual({ width: '100%' })
 })
+
+test('shimmed width only supports width prop', () => {
+  const a = systemWidth({
+    width: 1,
+    height: 32,
+    maxWidth: 768,
+  })
+  expect(a).toEqual({ width: '100%' })
+})