Jynx logoJynx

Units

Handling units between different value types

Overview

Many style function props are able to receive values in the form of both string and number, however not all of them accept numeric values in the units of px.

Jynx implements a utility, abstracted from the emotion library, to help determine whether a prop accepts px values and convert any numbers if it does.

This means, for props that accept string and number values, you can pass values with confidence, knowing that Jynx will handle the units.

Examples

To illustrate this, we can look at examples of both a prop that does accept px values (marginTop) and one that doesn't (zIndex).

Both of these props accept either a string, a number or a responsive style containing string | number as values.

To start with, you can pass any string value you like (whether it's a global keyword like inherit or a numeric value with units like '20rem'), and that value will be used as raw CSS.

/* margin-top: initial; */
<Component mt='initial' />


/* z-index: inherit; */
<Component z='inherit' />


/* margin-top: 4em; */
<Component mt='4em' />


/* z-index: 2; */
<Component z='2' />

Props that do accept px values

marginTop is a property that does accept px values.

Therefore, if the value passed to it is a number (or numeric-string e.g. '32'), it will be converted to px.

/* `16px` will be used */
<Component mt={16} />


/* `32px` will be used */
<Component mt='32' />

Props that do not accept px values

zIndex, on the other hand, does not accept px values.

This means if a number (or numeric-string e.g. '4') is passed to it then it's left untouched as raw CSS.

/* `1` will be used */
<Component z={1} />


/* `4` will be used */
<Component z='4' />

Theme Values

The one exception when it comes to handling numeric arguments, is theme values.

When a prop is associated with a theme scale, the parser will first attempt to use the provided value to retrieve a value from that scale. If unsuccessful, the provided value will be returned as a fallback.

When the given scale is defined as an array, a number can be used to attempt to retrieve the value at that array index and act as a fallback if it is greater than theme.scale.length.

This value is then parsed in the same way as any other (i.e. converted to px if it's numeric and passed to a prop that accepts px values).

When using string-based scales

const theme = {
    space: ['0rem', '0.125rem', '0.25rem', '0.5rem', '1rem', '2rem'],
    zIndices: ['0', '1', '2', '3', '4']
}


/**
 * The retrieved value is a string with units specified, therefore
 * regardless of whether it's passed to a prop that accepts
 * px values, the raw value will be used
 *
 * space[2] => '0.25rem'
 */
<Component mt={2} />


/**
 * The retrieved value is a string with units specified, therefore
 * regardless of whether it's passed to a prop that accepts
 * px values, the raw value will be used
 *
 * zIndices[2] => '2'
 */
<Component z='2' />

When using numeric scales

const theme = {
    space: [0, 2, 4, 8, 16, 24],
    zIndices: [0, 1, 2, 3, 4]
}


/**
 * The retrieved value is numeric and passed to a prop that accepts
 * px values, therefore units will be added
 *
 * space[2] => 4 => '4px'
 */
<Component mt={2} />


/**
 * The retrieved value is numeric but not passed to a prop that
 * accepts px values, therefore units will `not` be added
 *
 * zIndices[3] => 3 => '3'
 */
<Component z={3} />

When value > scale.length

/**
 * The value is greater than `theme.scale.length` and so
 * returns no value from the scale.
 *
 * In this case, the original value is used and, as this is
 * both numeric and passed to a prop that accepts px values,
 * therefore units will be added
 *
 * space[16] => undefined => 16 => '16px'
 */
<Component mt={16} />


/**
 * The value is greater than `theme.scale.length` and so
 * returns no value from the scale.
 *
 * In this case, the original value is used and, as whilst
 * this is numeric, it's passed to a prop that does not accept
 * px values, therefore units will `not` be added
 *
 * zIndices[8] => undefined => 8 => '8'
 */
<Component z={8} />