Skip to content

Commit

Permalink
WIP Omits invalid props
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Feb 12, 2020
1 parent 7499085 commit 7d2b300
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/atomic-layout-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ export {
/* Utilities */
export { default as warn } from './utils/functions/warn'
export { default as compose } from './utils/functions/compose'
export { default as omit } from './utils/functions/omit'
export { default as omitProps } from './utils/functions/omit/omitProps'
export { default as throttle } from './utils/functions/throttle'
export { default as transformNumeric } from './utils/math/transformNumeric'
2 changes: 2 additions & 0 deletions packages/atomic-layout-core/src/utils/functions/omit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './omit'
export * from './omit'
26 changes: 26 additions & 0 deletions packages/atomic-layout-core/src/utils/functions/omit/omit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import omit from './omit'

describe('omit', () => {
describe('given an object and a set of keys to omit', () => {
let result: ReturnType<typeof omit>
const obj = {
a: 1,
b: 2,
c: 3,
d: 4,
}

beforeAll(() => {
result = omit(['b', 'd'], obj)
})

it('should not include omitted keys in the result', () => {
expect(result).not.toContain(['b', 'c'])
})

it('should preserve unaffected keys', () => {
expect(result).toHaveProperty('a', 1)
expect(result).toHaveProperty('c', 3)
})
})
})
12 changes: 12 additions & 0 deletions packages/atomic-layout-core/src/utils/functions/omit/omit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function omit<R = Record<string, any>>(
keys: string[],
obj: R,
): Omit<R, keyof typeof keys> {
return Object.keys(obj).reduce<any>((acc, key) => {
if (!keys.includes(key)) {
acc[key] = (obj as any)[key]
}

return acc
}, {})
}
37 changes: 37 additions & 0 deletions packages/atomic-layout-core/src/utils/functions/omit/omitProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import capitalize from '../../strings/capitalize'
import Layout from '../../../Layout'
import propAliases from '../../../const/propAliases'
import memoizeWith from '../memoizeWith'

const breakpoints = Object.keys(Layout.breakpoints)
const responsiveProps = Object.keys(propAliases)
const allResponsiveProps = responsiveProps.reduce((acc, prop) => {
return acc.concat(
prop,
`${prop}Down`,
`${prop}Only`,
...breakpoints.map((breakpointName) => {
const responsivePropName = `${prop}${capitalize(breakpointName)}`
return [`${responsivePropName}Down`, `${responsivePropName}Only`]
}),
)
}, [])
const regExp = new RegExp(allResponsiveProps.join('|'))

function omitProps<P extends Record<string, any>>(props: P) {
return Object.keys(props).reduce((acc, key) => {
if (!regExp.test(key)) {
acc[key] = props[key]
}

return acc
}, {} as Record<string, any>)
}

const memoizeWithPairs = memoizeWith<typeof omitProps>((props) =>
Object.keys(props)
.map((key) => [key, props[key]])
.join(),
)

export default memoizeWithPairs(omitProps)
14 changes: 12 additions & 2 deletions packages/atomic-layout/src/components/Box.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as React from 'react'
import styled from 'styled-components'
import { BoxProps, applyStyles } from '@atomic-layout/core'
import { BoxProps, omitProps, applyStyles } from '@atomic-layout/core'

const Box: React.FC<BoxProps> = styled.div<BoxProps>`
const Box: React.FC<BoxProps> = styled(
({ as: As = 'div', ...rest }: BoxProps) => <As {...omitProps(rest)} />,
)`
display: ${({ flex, inline }) =>
flex
? inline
Expand All @@ -17,4 +19,12 @@ const Box: React.FC<BoxProps> = styled.div<BoxProps>`
}
`

/**
* @todo Export a regular Box by default to be used by Emotion,
* which does attributes clean up by default.
* Export a Box with responsive props omitted for styled-components
* version.
*/
// export const BoxWithoutAttributesPolution

export default Box
1 change: 1 addition & 0 deletions packages/atomic-layout/src/components/Composition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
generateComponents,
applyStyles,
warn,
omitProps,
} from '@atomic-layout/core'
import Box from './Box'
import { withPlaceholder } from '../utils/withPlaceholder'
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1155,11 +1155,23 @@
dependencies:
"@emotion/memoize" "0.7.3"

"@emotion/is-prop-valid@^0.8.6":
version "0.8.6"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz#4757646f0a58e9dec614c47c838e7147d88c263c"
integrity sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ==
dependencies:
"@emotion/memoize" "0.7.4"

"@emotion/[email protected]":
version "0.7.3"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78"
integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==

"@emotion/[email protected]":
version "0.7.4"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==

"@emotion/serialize@^0.11.12", "@emotion/serialize@^0.11.14":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.14.tgz#56a6d8d04d837cc5b0126788b2134c51353c6488"
Expand Down

0 comments on commit 7d2b300

Please sign in to comment.