Skip to main content
Version: current

CSS Mapping

@deity/falcon-ui uses a mapping function to define 2 things:

  • CSS property shortcuts, 'responsive props'
  • Which key from the theme object is used for each CSS property.

CSS Shortcuts / Responsive Props#

To keep your code slim @deity/falcon-ui maps certain component props to css properties.

client/src/components/myComponent.js

<Box m="xl">...

In the above example m relates to margin.

Assigning a blank object to a CSS Shortcut / Responsive Prop#

display: {},

In the above example we have assigned display and empty object. This allows for the property to be recognized and used for the theming of components.

Another benefit, provided by TypeScript - the property display will be hinted to you via IntelliSense as a valid property.

<Box display="block">

The property can be assigned a string as a value.

Shortcut map#

m: {
cssProp: 'margin',
themeProp: 'spacing'
},
mt: {
cssProp: 'marginTop',
themeProp: 'spacing'
},
ml: {
cssProp: 'marginLeft',
themeProp: 'spacing'
},
mr: {
cssProp: 'marginRight',
themeProp: 'spacing'
},
mb: {
cssProp: 'marginBottom',
themeProp: 'spacing'
},
mx: {
themeProp: 'spacing',
transformToCss: value => ({
marginLeft: value,
marginRight: value
})
},
my: {
themeProp: 'spacing',
transformToCss: value => ({
marginTop: value,
marginBottom: value
})
},
p: {
cssProp: 'padding',
themeProp: 'spacing'
},
pt: {
cssProp: 'paddingTop',
themeProp: 'spacing'
},
pl: {
cssProp: 'paddingLeft',
themeProp: 'spacing'
},
pr: {
cssProp: 'paddingRight',
themeProp: 'spacing'
},
pb: {
cssProp: 'paddingBottom',
themeProp: 'spacing'
},
px: {
themeProp: 'spacing',
transformToCss: value => ({
paddingLeft: value,
paddingRight: value
})
},
py: {
themeProp: 'spacing',
transformToCss: value => ({
paddingTop: value,
paddingBottom: value
})
},
height: {
themeProp: 'sizes'
},
minHeight: {
themeProp: 'sizes'
},
maxHeight: {
themeProp: 'sizes'
},
width: {
themeProp: 'sizes'
},
minWidth: {
themeProp: 'sizes'
},
maxWidth: {
themeProp: 'sizes'
},
size: {
themeProp: 'sizes',
transformToCss: value => ({
height: value,
width: value
})
},
minSize: {
themeProp: 'sizes',
transformToCss: value => ({
minHeight: value,
minWidth: value
})
},
maxSize: {
themeProp: 'sizes',
transformToCss: value => ({
maxHeight: value,
maxWidth: value
})
},
gridGap: {
themeProp: 'spacing'
},
gridRowGap: {
themeProp: 'spacing'
},
gridColumnGap: {
themeProp: 'spacing'
},
color: {
cssProp: 'color',
themeProp: 'colors'
},
bg: {
cssProp: 'backgroundColor',
themeProp: 'colors'
},
fill: {
themeProp: 'colors'
},
stroke: {
themeProp: 'colors'
},
borderColor: {
themeProp: 'colors'
},
bgFullWidth: {
themeProp: 'colors',
transformToCss: value => ({
position: 'relative',
zIndex: 1,
':before': {
content: '""',
width: '200vw',
height: '100%',
background: value,
position: 'absolute',
left: '-50vw',
right: '50vw',
top: 0,
zIndex: -1
}
})
},
fontSize: {
themeProp: 'fontSizes'
},
fontFamily: {
themeProp: 'fonts'
},
lineHeight: {
themeProp: 'lineHeights'
},
fontWeight: {
themeProp: 'fontWeights'
},
letterSpacing: {
themeProp: 'letterSpacings'
},
border: {
themeProp: 'borders'
},
borderTop: {
themeProp: 'borders'
},
borderRight: {
themeProp: 'borders'
},
borderBottom: {
themeProp: 'borders'
},
borderLeft: {
themeProp: 'borders'
},
borderRadius: {
themeProp: 'borderRadius'
},
boxShadow: {
themeProp: 'boxShadows'
},
position: {},
transitionTimingFunction: {
themeProp: 'easingFunctions'
},
transitionDuration: {
themeProp: 'transitionDurations'
},
opacity: {
themeProp: 'opacities'
},
textDecoration: {
themeProp: 'textDecorations'
},
top: {},
right: {},
bottom: {},
left: {},
display: {},
visibility: {},
alignItems: {},
justifyContent: {},
flexWrap: {},
flexDirection: {},
flex: {},
alignContent: {},
justifySelf: {},
justifyItems: {},
textAlign: {},
alignSelf: {},
order: {},
flexBasis: {},
gridColumn: {},
gridRow: {},
gridAutoFlow: {},
gridAutoRows: {},
gridAutoColumns: {},
gridTemplateRows: {},
gridTemplateColumns: {},
gridTemplateAreas: {},
gridArea: {},
gridTemplate: {},
overflow: {},
overflowX: {},
overflowY: {},
cursor: {}

Theme object mapping#

When you create a theme it has various keys; colors, fontSizes. Each of these then contains values. These are mapped to css properties meaning that the correct value is passed.

client/src/styling/theme.js

export const falconThemeV2 = createTheme({
colors: {
primary: '#262828',
secondary: '#EEEDEB'
},
spacing: {
xxs: 4,
xs: 8
},
fontSizes: {
xxs: 11,
xs: 12
},
...
})

client/src/components/myComponent.js

<Box color='primary' py='xxs'>
...
</Box>

In the above example you can see the prop, py="xxs". In the theme object you can there is both spacing.xxs and fontSizes.xxs. This is where the mapping comes in.

If you look in @deity/falcon-ui/src/theme/responsiveprops.ts you will see where these properties are mapped. You will see the themeProp which refers to which key in the theme object, and cssProp which is the css property it's mapped to.

@deity/falcon-ui/src/theme/responsiveprops.ts

m: {
themeProp: 'spacing';
}

Property map#

m: {
themeProp: 'spacing'
},
mt: {
themeProp: 'spacing'
},
ml: {
themeProp: 'spacing'
},
mr: {
themeProp: 'spacing'
},
mb: {
themeProp: 'spacing'
},
mx: {
themeProp: 'spacing',
},
my: {
themeProp: 'spacing',
},
p: {
themeProp: 'spacing'
},
pt: {
themeProp: 'spacing'
},
pl: {
themeProp: 'spacing'
},
pr: {
themeProp: 'spacing'
},
pb: {
themeProp: 'spacing'
},
px: {
themeProp: 'spacing',
},
py: {
themeProp: 'spacing',
},
height: {
themeProp: 'sizes'
},
minHeight: {
themeProp: 'sizes'
},
maxHeight: {
themeProp: 'sizes'
},
width: {
themeProp: 'sizes'
},
minWidth: {
themeProp: 'sizes'
},
maxWidth: {
themeProp: 'sizes'
},
size: {
themeProp: 'sizes',
},
minSize: {
themeProp: 'sizes',
},
maxSize: {
themeProp: 'sizes',
},
gridGap: {
themeProp: 'spacing'
},
gridRowGap: {
themeProp: 'spacing'
},
gridColumnGap: {
themeProp: 'spacing'
},
color: {
themeProp: 'colors'
},
bg: {
themeProp: 'colors'
},
fill: {
themeProp: 'colors'
},
stroke: {
themeProp: 'colors'
},
borderColor: {
themeProp: 'colors'
},
bgFullWidth: {
themeProp: 'colors',
},
fontSize: {
themeProp: 'fontSizes'
},
fontFamily: {
themeProp: 'fonts'
},
lineHeight: {
themeProp: 'lineHeights'
},
fontWeight: {
themeProp: 'fontWeights'
},
letterSpacing: {
themeProp: 'letterSpacings'
},
border: {
themeProp: 'borders'
},
borderTop: {
themeProp: 'borders'
},
borderRight: {
themeProp: 'borders'
},
borderBottom: {
themeProp: 'borders'
},
borderLeft: {
themeProp: 'borders'
},
borderRadius: {
themeProp: 'borderRadius'
},
boxShadow: {
themeProp: 'boxShadows'
},
transitionTimingFunction: {
themeProp: 'easingFunctions'
},
transitionDuration: {
themeProp: 'transitionDurations'
},
opacity: {
themeProp: 'opacities'
},
textDecoration: {
themeProp: 'textDecorations'
},
Unmapped properties

If you want to add CSS that isn't mapped you can pass a normal css object to the css prop e.g. css={{ top: 0 }}


Utility Functions#

Negative Spacings#

This function aims to provide you with additional spacing properties by adding a negative version of the positive number properties which are defined in the theme's spacing object.

// mapNegativeSpacings(theme: Theme): Theme
const themeWithNegativeSpacings = mapNegativeSpacings(theme);

It accomplishes the goal by taking the positive number's key and and prefixing it with a - and multiplying the number value by -1.

export const defaultBaseTheme = {
spacing: {
auto: 'auto',
none: 0,
xs: 8,
sm: 16,
md: 24,
lg: 32,
xl: 40,
xxl: 48,
xxxl: 64,
full: '100%',
},
};

The above theme will be replaced by the one below via the use of the utility function.

export const defaultBaseTheme = {
spacing: {
auto: 'auto',
none: 0,
xs: 8,
sm: 16,
md: 24,
lg: 32,
xl: 40,
xxl: 48,
xxxl: 64,
full: '100%',
-xs: -8,
-sm: -16,
-md: -24,
-lg: -32,
-xl: -40,
-xxl: -48,
-xxxl: -64
}
}

Grid Sizes#

This function allows you to generate custom properties for the sizes object.

// gridSizes(columnAmount: number, theme: Theme)
const themeWithGridSizes = gridSizes(8, theme);

By providing a columnAmount, the function will divide 100% by the columnAmount, that will be the increment amount. Each property will be calculated by performing a sum of the previous value and of the increment amount and mapped to a key representing the fraction.

The above-defined code will result in the following sizes properties:

export const defaultBaseTheme = {
sizes: {
'1/8': '12.5%',
'2/8': '25%',
'3/8': '37.5%',
'4/8': '50%',
'5/8': '62.5%',
'6/8': '75%',
'7/8': '87.5%',
},
};

Ask the community. #help

If you can't find what you're looking for, the answer might be on our community slack channel. Our team keep a close eye on this and will usually get back to you within a few hours, if not straight away. If you haven't created an account yet please sign up here slack.deity.io.

Stay up to date

Do you want to be informed when we release new features or fixes? Sign up to our newsletter to stay in the loop.