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} />