DEV Community

Artur Czemiel
Artur Czemiel

Posted on • Originally published at blog.graphqleditor.com

6 4

Power of typeof & typestyle in react apps

Have you ever heard of typestyle? No? It is a great no-webpack styling solutions. In my life I tried almost everything possible:

  • pure CSS
  • SCSS
  • SASS
  • CSS modules
  • CSS Next
  • inline react styles
  • typestyle

Most of solutions are bundled with webpack which means if you want to write library which have extendable replacable styles included you mustn't use webpack! So automatically you need to disqualificate these solutions:

  • CSS Next
  • CSS modules
  • SCSS
  • SASS
  • pure CSS

So lets take a closer look on these:

  • inline react styles
  • typestyle

Inline react styles are nice but producing spaghetti code

import * as React from 'react'
export const MyInlineComponent = ({ children, style }) => (
  <div
    style={{
      fontSize: 15,
      ...style,
    }}
  >
    {children}
  </div>
)
Enter fullscreen mode Exit fullscreen mode

Moreover you cannot include media and hover directives. Using onmouseover is ugly though and you need state to control that.

Lets try with typestyle then

import * as React from 'react'
import { style, classes, media } from 'typestyle'

export const MyComponentStyle = style(
  {
    fontSize: 15,
    $nest: {
      '&:hover': {
        fontSize: 18,
      },
    },
  },
  media({ maxWidth: 480 }, { fontSize: 10 })
)

// Extending the style

const MyNewStyle = classes(
  MyComponentStyle,
  style({
    color: '#0ae',
  })
)

export const MyStyledComponent = ({ children, style = '' }) => (
  <div className={classes(MyNewStyle, style)}>{children}</div>
)
Enter fullscreen mode Exit fullscreen mode

Looks great yeah? It is high time for advanced programmers style solution. Imagine a component which have more styles. I will write styles in separate file for this solution

styles.tsx

import { style } from 'typestyle'

export const Title = style({
  fontSize: 18,
})
export const SubTitle = style({
  fontSize: 18,
})
export const ImageSize = style({
  width: 20,
  height: 20,
})
Enter fullscreen mode Exit fullscreen mode

component.tsx

import * as React from 'react'
import * as styles from './styles'

export const MyStyledComponent = ({
  overrideStyles = {},
}: {
  overrideStyles: typeof styles
}) => {
  const componentStyles = {
    ...styles,
    ...overrideStyles,
  }
  return (
    <div>
      <div className={componentStyles.Title}>Hello</div>
      <div className={componentStyles.SubTitle}>World</div>
      <img
        className={componentStyles.ImageSize}
        src="https://source.unsplash.com/random"
      />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

usingComponent.tsx

import * as React from "react";
import { style } from "typestyle";
import { MyStyledComponent } from "./component";

const Page = () => (
  <div>
    <MyStyledComponent
      overrideStyles={{
        Title: style({
          color: "#00F"
        })
      }}
    />
  </div>
);

Enter fullscreen mode Exit fullscreen mode

Voila you can use the component and override its styles with full intelisense!! Just by using typeof on the module.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay