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 08e4be6 commit de2780c
Show file tree
Hide file tree
Showing 7 changed files with 92 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 @@ -52,5 +52,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 @@ -9,6 +9,7 @@ import {
generateComponents,
applyStyles,
warn,
omitProps,
} from '@atomic-layout/core'
import Box from './Box'
import { withPlaceholder } from '../utils/withPlaceholder'
Expand Down

0 comments on commit de2780c

Please sign in to comment.