Skip to content

Instantly share code, notes, and snippets.

@souporserious
Last active June 16, 2017 07:18
Show Gist options
  • Save souporserious/fde0a98212f85f0399c31926f575c1c6 to your computer and use it in GitHub Desktop.
Save souporserious/fde0a98212f85f0399c31926f575c1c6 to your computer and use it in GitHub Desktop.
React Text component for all of your text styling needs
import React from 'react'
import createStyledElement from 'create-styled-element'
import { parseToRgb } from 'polished'
import { createTone } from 'tonality'
import directionalStyles from './directional-styles'
// get "directionalStyles" here: https://gist.github.com/souporserious/54f9e56ebac4fc4dab603c4212f2ec2e
const systemFonts =
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"'
function parseColor(color, pseudo) {
const parsedColor = typeof color === 'object'
? pseudo ? { ...color[pseudo] } : { ...color }
: color
// if we are styling a pseudo state use the base color if it was not provided
if (!parsedColor.base && pseudo) {
parsedColor.base = color.base
}
// adjust the tone of the base color
if (parsedColor.tone) {
parsedColor.base = createTone(parsedColor.base)(parsedColor.tone)
}
// determine if we need to adjust the alpha channel or not
if (parsedColor.alpha) {
const { red, green, blue } = parseToRgb(parsedColor.base)
return `rgba(${red}, ${green}, ${blue}, ${parsedColor.alpha})`
} else {
return parsedColor.base || parsedColor
}
}
function Text({
component = 'span',
family,
weight = 300,
contrast = 1,
base = 16,
lineHeight = 1.5,
uppercase,
align,
underline,
truncate,
color = '#000000',
alpha = '0.79',
transition = 'color 160ms ease',
margin,
...props
}) {
let styles = {
fontFamily: family ? `${family} ${systemFonts}` : systemFonts,
textDecoration: underline ? 'underline' : 'none',
transition: transition,
}
if (weight) {
styles.fontWeight = weight
}
if (contrast) {
styles.fontSize = contrast * base
}
if (lineHeight) {
styles.lineHeight = `${lineHeight}`
}
if (uppercase) {
styles.transform = 'uppercase'
styles.letterSpacing = '0.05em'
}
if (align) {
styles.textAlign = align
}
if (truncate) {
styles.display = 'block'
styles.whiteSpace = 'nowrap'
styles.overflow = 'hidden'
styles.textOverflow = 'ellipsis'
}
if (color.base) {
styles.color = parseColor(color)
if (color.hover) {
styles[':hover'] = {
color: parseColor(color, 'hover'),
}
}
if (color.active) {
styles[':active'] = {
color: parseColor(color, 'active'),
}
}
} else if (color) {
styles.color = parseColor(color)
}
if (margin) {
styles = {
...styles,
...directionalStyles(margin, { prefix: 'margin', spacing: base }),
}
}
return createStyledElement(component, props)(styles)
}
export default Text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment