Jynx logoJynx

Types

Comprehensive definitions for Jynx's exported types

Styles

import CSS from 'csstype'

Though not directly exported from the package, a considerable amount of the Jynx's type system is derived from its use of csstype, an open source package providing strict TypeScript types for CSS styles based on MDN data.

Any instance where CSS is being accessed with dot-notation, this is the type being used.

interface CSSProperties extends CSS.StandardProperties<number | string>, CSS.SvgProperties<number | string> {}

The CSSProperties type is a marginally stricter abstraction of CSS.Properties type that combines standard CSS properties with SVG properties and allows the use of both number and string types within these.

Its main use case is to provide type definitions to values of a specific CSS property which is often accessed dynamically from the type using bracket notation.

Below is what an example implementation may look like:

const foo = <T extends keyof CSSProperties>(property: T, values: CSSProperties[T]) => {
  /* do something */
}

Here, property will be a string-key of CSSProperties and will be used to define the type for values. Therefore, if the argument for property is 'margin', the argument for values would need to be of the type CSSProperties.margin.

export type CSSInterpolation = number | string | CSSObject | undefined

In short, CSSInterpolation is a safer way of saying 'any CSS value'.

It acts as a starting point in situations where you know you need a CSS value but are unsure for what CSS property.

interface CSSObject extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObjectForCSSObject {}

The CSSObject type is essentially CSS as a POJO that is compatible with CSS-in-JS libraries.

In most cases it's used as a return type - primarily from style functions like color and space - and is taken directly from emotions types.

The type itself is an extended interface made up of a number of internal type definitions, all of which are essentially re-instantiations of CSSProperties, and can be see below for reference.

/**
 * CSSPropertiesWithMultiValues
 * @private
 */
type CSSPropertiesWithMultiValues = {
  [K in keyof CSSProperties]: CSSProperties[K]
}

/**
 * CSSPseudos
 * @private
 */
type CSSPseudos = {
  [K in CSS.Pseudos]?: CSSObject
}

/**
 * CSSOthersObjectForCSSObject
 * @private
 */
interface CSSOthersObjectForCSSObject {
  [propertiesName: string]: CSSInterpolation
}

It also helps to future-proof the library by integrating type support for pseudo selectors (a feature set to be added in an upcoming release).

type StyleProp<T> = T | ResponsiveStyle<T>

The StyleProp type is used to define any style declaration that will be passed to a style function, with a prime use case being in style function prop types like ColorProps and SpaceProps.

It takes a generic argument of T and allows its values to be either of type T or a ResponsiveStyle with each value being of type T.

As a simple example, if we wanted to type a property so that it could receive:

this would be the type to use.

/* Based on the type provided, this value could be: */
/* a number - e.g. 8 */
/* a string - e.g. '8px' */
/* a ResponsiveArray of number | string = e.g. [8, 16, '24px'] */
/* a ResponsiveObject of number | string = e.g. {_: 8, sm: '16px', md: 24} */

const prop: StyleProp<CSS.Property.Margin> = 8

Responsive

type ResponsiveArray<T> = [T, ...T]

ResponsiveArray is a tuple type used when defining responsive styles. It allows the variable to specify an array of values typed by the generic argument T, which are then mapped to media queries generated from the breakpoints in the current theme.

The first item in the array is required and therefore must be defined (in other words, you cannot use an empty array or never[] here).

You can then add as many additional items as necessary (hence the rest parameter) but be aware that once your array has more items than your theme has breakpoints, the surplus values will be disregarded.

type ResponsiveObject<T> = { _: T } & {
  [key in keyof DefaultTheme['breakpoints']]?: T
}

Like ResponsiveArray, the ResponsiveObject type is used when defining responsive styles. It allows the variable to specify an object containing key-value pairs where the keys reference keys of theme.breakpoints and the values are typed by the generic argument T.

The object must contain an item with the key '_' which is used as the initial value.

Subsequent entries are then added using a key that corresponds to that of the desired breakpoint and assigning it the value intended for the correlating screen size.

type ResponsiveStyle<T> = ResponsiveArray<T> | ResponsiveObject<T>

The ResponsiveStyle type is a simple intersection that allows a variable to be either a ResponsiveArray or a ResponsiveObject.

It take a generic argument of T which is used to type the values in the provided data structure.

Functions

type StyleFunction<T> = {
  (props: T & { theme: DefaultTheme }): CSSObject
  config: StyleFunctionConfig
}

The StyleFunction type is used to define a style function like color or space.

The type consists of the function itself which takes a single argument of props and returns a CSSObject. The props argument is an object which is defined by the generic argument of T combined with a theme property; typed as DefaultTheme. It returns a CSSObject which can then be parsed by CSS-in-JS libraries.

Style functions also contain a config object, accessible through *.config, which provides the StyleFunctionConfig used to create the function. This is used under the hood by the compose utility.

interface StyleFunctionConfig {
  [key: string]: {
    property: keyof CSSProperties
    scale?: keyof DefaultTheme
    transformer?: TransformFunction<any>
  }
}

StyleFunctionConfig is the type used to outline the structure of the config object passed to createStyleFunction.

It's made up of a series of 'CSS property keys' each defining:

  • property: the name of the CSS property used in the style object
  • scale: an optional string reference to the key within the theme object of the property's corresponding scale
  • transformer: an optional TransformerFunction used to alter the values before they're added to the style object

Visit the createStyleFunction page to see example config objects and how to use them.

type TransformFunction<T> = (
  value: T,
  scale?: DefaultTheme[keyof DefaultTheme] | Record<string, any> | any[]
) => T

The TransformFunction type is used to define any transformer that's passed in a StyleFunctionConfig. It takes a value typed by the generic argument T and must return a value of the same type.

It can also receive an optional scale object/array which the parser will attempt to retrieve the given value from before returning it as raw CSS.

The scale should ideally exist within the DefaultTheme, however, it is safe to also pass any object or array as, if the value is not found within the scale, then it's returned as raw CSS.

Theme

export interface BaseTheme {
  breakpoints: DefaultBreakpoints
  space?: ObjectOrArray<CSS.Property.Margin<string | number>>
  fontSizes?: ObjectOrArray<CSS.Property.FontSize<number>>
  colors?: ObjectOrArray<CSS.Property.Color>
  fonts?: ObjectOrArray<CSS.Property.FontFamily>
  fontWeights?: ObjectOrArray<CSS.Property.FontWeight>
  lineHeights?: ObjectOrArray<CSS.Property.LineHeight<number>>
  letterSpacings?: ObjectOrArray<CSS.Property.LetterSpacing<number>>
  sizes?: ObjectOrArray<CSS.Property.Height | CSS.Property.Width>
  borders?: ObjectOrArray<CSS.Property.Border>
  borderStyles?: ObjectOrArray<CSS.Property.Border>
  borderWidths?: ObjectOrArray<CSS.Property.BorderWidth<number>>
  radii?: ObjectOrArray<CSS.Property.BorderRadius<number>>
  shadows?: ObjectOrArray<CSS.Property.BoxShadow>
  transitions?: ObjectOrArray<CSS.Property.Transition>
  zIndices?: ObjectOrArray<CSS.Property.ZIndex>
}

The BaseTheme interface is a loosely typed object that acts as a fallback when a CustomTheme is not defined.

It helps to maintain a base level of strictness by providing the parser with a rough idea of what to expect for certain values.

interface CustomTheme {}

The CustomTheme type is an empty interface that can be extended with your own themes type, allowing type-safe access to theme values from within certain props.

type DefaultTheme = BaseIfEmpty<CustomTheme>

DefaultTheme is used throughout Jynx to provide access to the type of the current global theme.

It uses a internal custom utility type (BaseIfEmpty) to conditionally resolve to either CustomTheme or BaseTheme depending on whether CustomTheme has been defined/extended.

type ThemeValue<T extends keyof DefaultTheme> = DefaultTheme[T] extends string | number
  ? DefaultTheme[T]
  : DeepLeaves<DefaultTheme[T]>

The ThemeValue can be used as a way to access theme values from within a style functions property.

It takes a generic argument of T which is a string reference to the key of the corresponding scale within the theme that the theme values should be taken from.

If the 'scale' is a string or a number (i.e. a single value as opposed to an object/array) then that value is used, otherwise an internal utility type (DeepLeaves) is used to recursively obtain all the nested keys and create a tuple from them using dot-notation.

type ThemeProps<T> = {
  theme: T
}

ThemeProps is used to tell the compiler that a variable receives a theme as one of its props.

It takes a generic argument of T which is used as the type of the theme prop.