Giter Club home page Giter Club logo

typestyle's Introduction

TypeStyle

Join the chat at  gitter

Making CSS type safe.

Build Status NPM version

Writing CSS with TypeStyle will be just as fluent as writing JavaScript with TypeScript.

There are quite a few css in js frameworks out there. This one is different:

  • Provides great TypeScript developer experience.
  • No custom AST transform or module loader support needed.
  • Works with any framework (react, angular2, cyclejs, whatever, doesn't matter).
  • Zero config. Just use.
  • super small (~1k)

This project is powered by github ๐ŸŒŸs ^ go ahead and star it please.

Checkout the awesome list of reviews ๐ŸŒน.

Overview

Quickstart

Use it like you would use CSS modules or CSS in general with webpack etc, but this time you get to use TypeScript / JavaScript!

Install npm install typestyle --save

Use

/** Import */
import {style} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({color: 'red'});

/** Use the class name in a framework of choice */
//  e.g. React
const MyButton =
  ({onClick,children})
    => <button className={className} onClick={onClick}>
        {children}
      </button>
// or Angular2
@Component({
  selector: 'my-component',
  template: `<div class="${className}">Tada</div>`
})
export class MyComponent {}

Play with it

Server Side

Just get the styles as CSS at any point and render it in a style tag yourself. e.g.

/** Import */
import {style, css} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({color: 'red'});

/** Render to CSS style tag */
const styleTag = `<style>${css()}</style>`
/** ^ send this as a part of your HTML response */

Advanced

Pseudo States &:hover, &:active, &:focus, &:disabled as you would expect e.g.

/** Import */
import {style} from "typestyle";

/** convert a style object to a CSS class name */
const className = style({
  color: 'blue',
  '&:hover': {
    color: 'red'
  }
});

Child selectors &>* etc work too e.g. use it to design a vertical layout:

/** Import */
import {style} from "typestyle";

/** Share constants in TS! */
const spacing = '5px';

/** style -> className :) */
const className = style({
  '&>*': {
    marginBottom: spacing,
  },
  '&>*:last-child': {
    marginBottom: '0px',
  }
});

Media Queries

const colorChangingClass = style({
  backgroundColor: 'red',
  '@media (min-width: 400px)': {
    backgroundColor: 'pink'
  }
})

Merge Objects Pass as many style objects to style and they merge just right.

const redMaker = {color:'red'};
const alwaysRedClass = style(redMaker);
const greyOnHoverClass = style(
  redMaker,
  {'&:hover':{color: 'grey'}}
);

Compose Classes You can easily compose class names using classes

const tallClass = style({height:'100px'});
const redClass = style({color:'red'});

/** Compose classes */
const tallRedClass = typestyle.classes(tallClass, redClass);

/** Even conditionally (any falsy parameters are ignored in the composed class name) */
const mightBeRed = typestyle.classes(tallClass, hasError && redClass);

Animations Use keyframes to define an animation and get the animation name

const colorAnimationName = typestyle.keyframes({
  from: { color: 'red' },
  to: { color: 'blue' }
})

const ooooClass = typestyle.style({
  animationName: colorAnimationName,
  animationDuration: '1s'
});

TypeScript Protip: namespace

/** Think of it like an inline stylesheet */
namespace MyStyles {
  const color = 'red';

  export const alwaysRedClass = style({color});
  export const onlyRedOnHoverClass = style({'&:hover':{color});
}

/** Use e.g. with React */
const AlwaysRed = ({text}) => <div className={MyStyles.alwaysRedClass}>{text}</div>
const OnlyRedOnHover = ({text}) => <div className={MyStyles.onlyRedOnHoverClass}>{text}</div>

Fallbacks

There are two kinds of fallbacks in CSS and both are supported:

  • Same key multiple values: Just use an array for the value e.g. background colors
const fallBackBackground = style({
  backgroundColor: [
    /* The fallback */
    'rgb(200, 54, 54)',
    /** Graceful upgrade */
    'rgba(200, 54, 54, 0.5)'
  ]
});
  • Vendor prefixing: Anything that starts with - is not case renamed (i.e. no fooBar => foo-bar) e.g. for smooth scroll:
const scroll = style({
  '-webkit-overflow-scrolling': 'touch',
  overflow: 'auto'
});

Protip: Big fan of flexbox? Use csx as it provides the necessary vendor prefixes so you don't need to worry about them.

Note: We don't do automatic vendor prefixing for a few reasons:

CSS Replacement

You can even use any raw CSS selector as well using cssRule e.g.

  • To setup a application style layout:
/** Use full window size for application */
cssRule('html, body', {
  height: '100%',
  width: '100%',
  padding: 0,
  margin: 0
});
  • Font faces:
cssRule('@font-face', {
  fontFamily: '"Bitstream Vera Serif Bold"',
  src: 'url("https://mdn.mozillademos.org/files/2468/VeraSeBd.ttf")'
});
  • Page level media queries:
/** Save ink with a white background */
cssRule('@media print', {
  body: {
    background: 'white'
  }
});

Advantage: cssRule(selector,properties) works seemlessly in a nodejs enviroment (for testing) whereas require('./someCss.css') does not without additional setup.

CSX

We understand that its difficult to get started with CSS in JS without additional guidance. So we also provide a lot of utility style objects in typestyle/csx to decrease you rampup. e.g. flexbox:

import * as csx from 'typestyle/lib/csx';
import {style} from 'typestyle';

const horizontal = style(csx.horizontal);

/** Sample usage with React */
var Demo = () =>
  <div className={horizontal}>
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
  </div>;

Of course you can compose styles easily:

import * as csx from 'typestyle/lib/csx';
import {style} from 'typestyle';

const flexHorizontalGreen = style(
  csx.flex,
  csx.horizontal,
  { backgroundColor: 'green' }
);

/** Sample usage with React */
const Demo = () =>
  <div className={flexHorizontalGreen}>
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
  </div>;

Type-safe colors and more

To make it easier to work with colors, TypeStyle has a lot of the same color functions as SASS or LESS built-in with type definitions. This means that writing CSS in JS is even easier than ever!

Here is an example of some of the ways colors can be used together.

import { rgb, black } from 'typestyle/lib/csx';

const primaryColor = rgb(0, 0, 255);
const primaryBgColor = primaryColor.darken('30%').desaturate('10%');
const primaryBoldColor = primaryColor.mix(black);
const invertedColor = black.lighten('20%');
const invertedBgColor = primaryBgColor.invert();

const buttonStyles = style({
  color: primaryColor,
  backgroundColor: primaryBgColor
});

const invertedButtonStyles = style({
  color: invertedColor,
  backgroundColor: invertedBgColor
});

If you need to do testing with these colors, you can even print them to console by calling the .toString() method.

console.log(red.toString()); // prints 'rgb(255,0,0)'

Book

We really really want to make CSS maintainable and simple. So we even wrote a free and open source book for how to use the utility styles in typestyle/lib/csx ๐ŸŒน. Jump to the book

How

This works very much in the same principle as CSS modules in that it takes a style object and generates a non conflicting generated class name.

Really How

  • FreeStyle converts a JS style object to a CSS className using hashing
  • We keep a single style sheet updated as you register styles.
  • Provide css.d.ts to help with autocomplete + error reporting.

Help

Really apprecate as many PRs for css.d.ts CSSProperties as you can throw at us ๐ŸŒน

Performance

Same as FreeStyle which is super simple and does the absolute minimum but necessary, so faster than other CSS in JS frameworks for sure. We'd love to be told otherwise.

typestyle's People

Contributors

basarat avatar notoriousb1t avatar notoriousbot avatar styfle avatar wmaurer avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.