0.0.1 • Published 5 years ago

component-stylesheets v0.0.1

Weekly downloads
3
License
-
Repository
-
Last release
5 years ago

Component Stylesheets

Motivation

I am working on this project with the aim to replace styled-components. I hope to be able to offer a similar development experience without the performance drawbacks and being able to better integrate with existing CSS ecosystems like SASS, LESS or Stylus.

Basics

// index.scss
:component(h4.MyHeading) {
  background: white;
  color: black
}

// index.jsx
import * as C from './index.scss';

...

const Example = props => <C.MyHeading>Hello World</C.MyHeading>

Static Props

You can specify static props for each of your components. Similar to attrs from styled components.

// index.scss
:component(h4.MyHeading) {
  :props {
    aria-hidden: false !important; // can't override
    role: presentation;
  }

  background: white;
  color: black
}

// index.jsx
import * as C from './index.scss';

...

const Example = props => <C.MyHeading>Hello World</C.MyHeading>

Dynamic props

You can use runtime props like css variables. Those rules are removed from the stylesheet and applied at runtime via a backend of your choice like styled-components or even just using the style prop:

:component(h4.MyHeading) {
  :props {
    aria-hidden: false !important; // can't override
    role: presentation;
  }

  background: white;
  color: prop('textColor');
}

States

States are a shorthand for classes. If you have a :state(.selected) {} in your component, its rules will be applied if the selected prop is truthy:

// index.scss
:component(div.MyExample) {
  background: red;

  :state(.blue) {
    background: blue;
  }
}

// index.jsx
import * as C from './index.scss';

const BlueBackground = <C.MyExample blue />;

Children

// index.scss
:component(div.MyExample) {
  :props {
    aria-hidden: false !important; // can't override
    role: presentation;
  }

  :child(span) {
    content: 'Hello';
    color: white;
  }

  // no wrapper node, similar to Fragment
  //
  // by default, children of <MyExample> would be placed
  // after all builtin children, so we use a `:child` with
  // `content: prop('children')` to override that behavior
  //
  // using `content: prop('children')` prevents the compiler
  // from placing the implicit `children` as the last node
  :child {
    content: prop('children');
  }

  :child(span) {
    content: ' World';
    color: green;
  }

  background: blue;
}

Composition / Inheritance

TODO: ...just use mixins??