Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ All of these CSS properties are supported. You can pass either a string or a num
- `alignContent`
- `alignItems`
- `alignSelf`
- `animation`
- `animationDelay`
- `animationDirection`
- `animationDuration`
- `animationFillMode`
- `animationIterationCount`
- `animationName`
- `animationPlayState`
- `animationTimingFunction`
- `background`
- `backgroundBlendMode`
- `backgroundClip`
Expand Down Expand Up @@ -133,6 +142,7 @@ All of these CSS properties are supported. You can pass either a string or a num
- `clear`
- `color`
- `columnGap`
- `content`
Copy link
Contributor Author

@brandongregoryscott brandongregoryscott Nov 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After pulling in this change to Evergreen locally and swapping out glamor, the Overlay component wasn't showing the transparent grey background due to the missing content: ""; rule (https://github.com/segmentio/evergreen/blob/master/src/overlay/src/Overlay.js#L54). Since this isn't directly related to animations/keyframes, I can revert this change and make a separate PR for it if desired.

- `cursor`
- `display`
- `flex`
Expand Down Expand Up @@ -269,6 +279,35 @@ Utility function for filtering out `Box` props. Returns an `{ matchedProps, rema

Type: `object`

#### keyframes(name, timeline)

Function for generating an animation keyframe name and injecting the provided styles into the stylesheet. The `timeline` object is in the shape of `{ 'from' | 'to' | [0-100]: CssProps }` which define the styles to apply at each position of the animation. Returns the generated name for use with the `animation` or `animationName` props.

```tsx
import Box, { keyframes } from 'ui-box'

const openAnimation = keyframes('openAnimation', {
from: {
opacity: 0,
transform: 'translateY(-120%)'
},
to: {
transform: 'translateY(0)'
}
})

const AnimatedBox = () => <Box animation={`${openAnimation} 240ms cubic-bezier(0.175, 0.885, 0.320, 1.175)`} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥


// Equivalent using individual props:
const AnimatedBox = () => (
<Box
animationName={openAnimation}
animationDuration={240}
animationTimingFunction="cubic-bezier(0.175, 0.885, 0.320, 1.175)"
/>
)
```

#### propTypes

Object of all the `Box` CSS property `propTypes`.
Expand All @@ -289,6 +328,7 @@ Object of all the CSS property enhancers (the methods that generate the class na

These enhancer groups are also exported. They're all objects with `{ propTypes, propAliases, propEnhancers }` properties. They're mainly useful for if you want to inherit a subset of the `Box` CSS propTypes in your own components.

- `animation`
- `background`
- `borderRadius`
- `borders`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
"size-limit": [
{
"path": "dist/src/index.js",
"limit": "50 KB",
"limit": "55 KB",
"running": false,
"gzip": false
}
Expand Down
4 changes: 2 additions & 2 deletions src/enhance-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { BoxPropValue, EnhancerProps } from './types/enhancers'

type PreservedProps = Without<React.ComponentProps<any>, keyof EnhancerProps>

interface EnhancedPropsResult {
interface EnhancePropsResult {
className: string
enhancedProps: PreservedProps
}
Expand All @@ -21,7 +21,7 @@ export default function enhanceProps(
props: EnhancerProps & React.ComponentPropsWithoutRef<any>,
selectorHead = '',
parentProperty = ''
): EnhancedPropsResult {
): EnhancePropsResult {
const propsMap = expandAliases(props)
const preservedProps: PreservedProps = {}
let className: string = props.className || ''
Expand Down
95 changes: 95 additions & 0 deletions src/enhancers/animation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import PropTypes from 'prop-types'
import getCss from '../get-css'
import { PropValidators, PropTypesMapping, PropEnhancerValueType, PropAliases, PropEnhancers } from '../types/enhancers'

export const propTypes: PropTypesMapping = {
animation: PropTypes.string,
animationDelay: PropTypes.string,
animationDirection: PropTypes.string,
animationDuration: PropTypes.string,
animationFillMode: PropTypes.string,
animationIterationCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
animationName: PropTypes.string,
animationPlayState: PropTypes.string,
animationTimingFunction: PropTypes.string
}

export const propAliases: PropAliases = {}

export const propValidators: PropValidators = {}

const animation = {
className: 'a',
cssName: 'animation',
jsName: 'animation',
complexValue: true
}

const animationDelay = {
className: 'a-dly',
cssName: 'animation-delay',
jsName: 'animationDelay',
defaultUnit: 'ms'
}

const animationDirection = {
className: 'a-dir',
cssName: 'animation-direction',
jsName: 'animationDirection',
safeValue: true
}

const animationDuration = {
className: 'a-dur',
cssName: 'animation-duration',
jsName: 'animationDuration',
defaultUnit: 'ms'
}

const animationFillMode = {
className: 'a-fill-md',
cssName: 'animation-fill-mode',
jsName: 'animationFillMode',
safeValue: true
}

const animationIterationCount = {
className: 'a-itr-ct',
cssName: 'animation-iteration-count',
jsName: 'animationIterationCount',
defaultUnit: ''
}

const animationName = {
className: 'a-nm',
cssName: 'animation-name',
jsName: 'animationName'
}

const animationPlayState = {
className: 'a-ply-ste',
cssName: 'animation-play-state',
jsName: 'animationPlayState',
safeValue: true
}

const animationTimingFunction = {
className: 'a-tmng-fn',
cssName: 'animation-timing-function',
jsName: 'animationTimingFunction',
complexValue: true
}

export const propEnhancers: PropEnhancers = {
animation: (value: PropEnhancerValueType, selector: string) => getCss(animation, value, selector),
animationDelay: (value: PropEnhancerValueType, selector: string) => getCss(animationDelay, value, selector),
animationDirection: (value: PropEnhancerValueType, selector: string) => getCss(animationDirection, value, selector),
animationDuration: (value: PropEnhancerValueType, selector: string) => getCss(animationDuration, value, selector),
animationFillMode: (value: PropEnhancerValueType, selector: string) => getCss(animationFillMode, value, selector),
animationIterationCount: (value: PropEnhancerValueType, selector: string) =>
getCss(animationIterationCount, value, selector),
animationName: (value: PropEnhancerValueType, selector: string) => getCss(animationName, value, selector),
animationPlayState: (value: PropEnhancerValueType, selector: string) => getCss(animationPlayState, value, selector),
animationTimingFunction: (value: PropEnhancerValueType, selector: string) =>
getCss(animationTimingFunction, value, selector)
}
6 changes: 6 additions & 0 deletions src/enhancers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as animation from './animation'
import * as background from './background'
import * as borderRadius from './border-radius'
import * as borders from './borders'
Expand All @@ -20,6 +21,7 @@ import * as transition from './transition'
import { PropValidators, PropEnhancers, PropAliases, PropTypesMapping } from '../types/enhancers'

export {
animation,
background,
borderRadius,
borders,
Expand All @@ -42,6 +44,7 @@ export {
}

export const propTypes: PropTypesMapping = {
...animation.propTypes,
...background.propTypes,
...borderRadius.propTypes,
...borders.propTypes,
Expand All @@ -66,6 +69,7 @@ export const propTypes: PropTypesMapping = {
export const propNames = Object.keys(propTypes)

export const propAliases: PropAliases = {
...animation.propAliases,
...background.propAliases,
...borderRadius.propAliases,
...borders.propAliases,
Expand All @@ -88,6 +92,7 @@ export const propAliases: PropAliases = {
}

export const propValidators: PropValidators = {
...animation.propValidators,
...background.propValidators,
...borderRadius.propValidators,
...borders.propValidators,
Expand All @@ -110,6 +115,7 @@ export const propValidators: PropValidators = {
}

export const propEnhancers: PropEnhancers = {
...animation.propEnhancers,
...background.propEnhancers,
...borderRadius.propEnhancers,
...borders.propEnhancers,
Expand Down
36 changes: 27 additions & 9 deletions src/enhancers/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import PropTypes from 'prop-types'
import getCss from '../get-css'
import { getClassNamePrefix } from '../get-class-name'
import { PropEnhancerValueType, PropValidators, PropEnhancers, PropTypesMapping, PropAliases } from '../types/enhancers'
import { Rule } from '../prefixer'

export const propTypes: PropTypesMapping = {
boxSizing: PropTypes.string,
clear: PropTypes.string,
clearfix: PropTypes.bool,
content: PropTypes.string,
display: PropTypes.string,
float: PropTypes.string,
zIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
Expand All @@ -22,44 +24,60 @@ const display = {
safeValue: true,
isPrefixed: true
}

const float = {
className: 'flt',
cssName: 'float',
jsName: 'float',
safeValue: true
}

const clear = {
className: 'clr',
cssName: 'clear',
jsName: 'clear',
safeValue: true
}

const zIndex = {
className: 'z-idx',
cssName: 'z-index',
jsName: 'zIndex',
safeValue: true,
defaultUnit: ''
}

const boxSizing = {
className: 'box-szg',
cssName: 'box-sizing',
jsName: 'boxSizing',
safeValue: true
}

const clearfix = () => {
const className = `${getClassNamePrefix()}clearfix`
const rules: Rule[] = [
{ property: 'display', value: 'table' },
{ property: 'clear', value: 'both' },
{ property: 'content', value: '""' }
]
const concatenatedRules = rules.map(rule => ` ${rule.property}: ${rule.value};`).join('\n')
const styles = `\n.${className}:before, .${className}:after {\n${concatenatedRules}\n}`
return { className, rules, styles }
}

const content = {
className: 'cnt',
cssName: 'content',
jsName: 'content',
complexValue: true
}

export const propEnhancers: PropEnhancers = {
boxSizing: (value: PropEnhancerValueType, selector: string) => getCss(boxSizing, value, selector),
clear: (value: PropEnhancerValueType, selector: string) => getCss(clear, value, selector),
clearfix: () => ({
className: `${getClassNamePrefix()}clearfix`,
styles: `
.${getClassNamePrefix()}clearfix:before, .${getClassNamePrefix()}clearfix:after {
display: table;
clear: both;
content: "";
}`
}),
clearfix,
content: (value: PropEnhancerValueType, selector: string) => getCss(content, value, selector),
display: (value: PropEnhancerValueType, selector: string) => getCss(display, value, selector),
float: (value: PropEnhancerValueType, selector: string) => getCss(float, value, selector),
zIndex: (value: PropEnhancerValueType, selector: string) => getCss(zIndex, value, selector)
Expand Down
6 changes: 4 additions & 2 deletions src/get-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import prefixer, { Rule } from './prefixer'
import valueToString from './value-to-string'
import getClassName, { PropertyInfo } from './get-class-name'
import { EnhancedProp } from './types/enhancers'
import isProduction from './utils/is-production'

/**
* Generates the class name and styles.
Expand Down Expand Up @@ -34,7 +35,8 @@ export default function getCss(propertyInfo: PropertyInfo, value: string | numbe
}

let styles: string
if (process.env.NODE_ENV === 'production') {

if (isProduction()) {
const rulesString = rules.map(rule => `${rule.property}:${rule.value}`).join(';')
styles = `.${className}${selector}{${rulesString}}`
} else {
Expand All @@ -45,5 +47,5 @@ ${rulesString}
}`
}

return { className, styles }
return { className, styles, rules }
}
7 changes: 7 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@ import * as cache from './cache'
import * as styles from './styles'

export { default } from './box'
export { default as keyframes } from './keyframes'
export { default as splitProps } from './utils/split-props'
export { default as splitBoxProps } from './utils/split-box-props'
export { setClassNamePrefix } from './get-class-name'
export { configureSafeHref } from './utils/safeHref'
export { BoxProps, BoxOwnProps, EnhancerProps, PropsOf, PolymorphicBoxProps, BoxComponent } from './types/box-types'
export {
KeyframesPercentageKey,
KeyframesPositionalKey,
KeyframesTimeline,
KeyframesTimelineKey
} from './types/keyframes'

export {
background,
Expand Down
Loading