Git Product home page Git Product logo

nyancss's Introduction

๐ŸŒˆ Nyan CSS

Best of both worlds. Nyan CSS lets you write plain CSS while reaping benefits of CSS-in-JS.

Write a universal design system. You can reuse the same code anywhere starting from static HTML+CSS and ending with React and Vue.js without actually changing the CSS.

Minimalistic. BEM-inspired Nyan CSS convention consists just of 3 rules but it as bulletproof as BEM.

Use modern CSS. CoffeeScript long gone from the radars, yet we all loved it ;-) Stick to the platform to ensure the longevity of your code.

Skip to the convention | Join the community

Installation

See installation instructions for webpack.

Demo

CSS

.Header,
.Text {
  font-family: monospace;
}

.Header {
  font-size: 2rem;
}

.Header-size-large {
  font-size: 2.2rem;
}

.Text-italic {
  font-style: italic;
}

React code

See other options:

import React from 'react'
import { Header, Text } from './style.css'

function Announcement() {
  return (
    <>
      <Header tag="h1" size="large">
        Welcome Nyan CSS!
      </Header>
      <Text tag="marquee" italic>
        Please, welcome Nyan CSS!
      </Text>
    </>
  )
}

Result

A page in a browser with large "Welcome Nyan CSS" and moving italic "Please, welcome Nyan CSS!"

Other options

Show all options

Plain HTML

<h1 class="Header Header-size-large">
  Welcome Nyan CSS!
</h1>

<marquee class="Text Text-italic">
  Please, welcome Nyan CSS!
</marquee>

Vue.js

import Vue from 'vue'
import { Header, Text } from './style.css'

const Announcement = {
  components: {
    'custom-header': Header,
    'custom-text': Text
  },

  template: `
    <main>
      <custom-header tag='h1' size='large'>Welcome Nyan CSS!!</custom-header>
      <custom-text tag='marquee' italic='true'>Please, welcome Nyan CSS!</custom-text>
    </main>
  `
}

Preact

import { h } from 'preact'
import { Header, Text } from './style.css'

function Announcement() {
  return (
    <>
      <Header tag="h1" size="large">
        Welcome Nyan CSS!
      </Header>
      <Text tag="marquee" italic>
        Please, welcome Nyan CSS!
      </Text>
    </>
  )
}

Class names

import { Header, Text } from './style.css'

function Announcement() {
  return `
<h1 class='${Header({ size: 'large' })}'>Welcome Nyan CSS!</h1>
<marquee class='${Text({
    italic: true
  })}'>Please, welcome Nyan CSS!</marquee>
`
}

Convention

Component

.Component is a component class.

The name must be in ClassCase, e.g. .FormInput or .UI.

In this example, .Button represents <Button />.

.Button {
  color: white;
}

Boolean prop

.Component-disabled is a boolean prop class.

The name extension must be in camelCase, e.g. .FormInput-autoFocus or .UI-dev.

.Button-disabled {
  opacity: 0.5;
}

In the example, .Button-disabled is applied to the component when its disabled prop is truthy:

<Button tag="button" disabled>
  Whatever
</Button>

Enum prop

.ComponentName-color-gray is an enum prop class.

The name extensions must be in camelCase, e.g. .FormInput-borderColor-lightGray or .UI-env-dev.

.Button-color-red {
  background: red;
}

.Button-color-green {
  background: green;
}

.Button-color-red is applied to the component when its color prop equals "red":

<Button tag="button" color="red">
  Click Me
</Button>

Related packages

Changelog

See the changelog.

License

MIT ยฉ Sasha Koss

nyancss's People

Contributors

kossnocorp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nyancss's Issues

How to make work with @each loop

I'm trying to make this work with postcss-each and I'm running into some issues.

What I want to do is something like

React:

<MyComponent color="red" />

CSS:

@each $color in var(--colors) {
  .MyComponent-color-$color { background-color: $color; }
}

Where I'm getting an error Cannot read property '1' of null on this line in getComponents in the console, and none of my react application loads. Is there a better way to do this?

Define component tag in CSS

Is it a way to define tag in CSS? Like base from React CSS competent.

I think it will be nice to have it, since you will work it only once. Right now you can use your component in many places and it is easy to forget to set tag for Button.

TypeScript support

Do we have an TypeScript support?

If yes, we should add it to docs, because it is awesome :D.

refs are attached to the decss wrapper

Steps to reproduce
Attach a ref to a decss component

Expected Behavior
The ref is attached to the DOM node rendered

Actual Behavior
The ref is attached to the decss wrapper, making it impossible to e.g. focus wrapped element programmatically.

Question: How do you determine the html element to use?

In the example in the blog post, a <button> HTML element is rendered. At least, that's what's in the code you are refactoring.

But I could not wrap my head around how decss knows to use an HTML button instead of, say, a div.

So I peeked in the source and there I saw this:

 * // Usage with default props
 * const { Button, Icon } = decss(createElement, style, {
 *   Button: {tag: 'button', type: 'button'},
 *   Icon: {type: 'close'}
 * })
 * <Button><Icon />Close</Button>
 */
function decss (h, style, defaultProps) {

So... here are my questions:

  • Is it correct that defaultProps accepts a mapping from Component to HTML element/props?
  • If so, does this mean you can't use this mapping when using decss-loader?
  • If both of the above are true, could we maybe extend your rules to allow the html element to be specified? I was thinking along the lines of:
.Button {
  color: white;
}

Maps to

<div class="Button-23564">My button</div>

whereas

button.Button {
  color: white;
}

would map to

<button class="Button-23564">My button</button>

What's the best way to use styles on existing components?

I'm running into this issue using <Link>s from react router, for example. Given when I want to style a link, what I've been doing is

import { classNames } from 'app.css';

/* in the jsx */
<Link className={classNames.MyLinkStyle} to="/">Home</Link>

And that's fine but it would be super cool to pass a component like

import { MyLinkStyle } from 'app.css';

/* in the jsx */
<MyLinkStyle component={Link} to="/">Home</MyLinkStyle>

Zero-number children is not displayed

When Decss-components has only one children and it is equal 0 (number), it's not displayed

React example:

import {Block} from './style.css'

const Component = () => (
  <div>
    // displayed
    <Block children="0"/> 
    <Block>0</Block>

     // not displayed
    <Block children={0}/>
    <Block>{0}</Block>
  </div>
)

Parcel

Hello! Great lib, thanks for it. I want use it with Parcel, could you explain, how I can do it?

Classes mixing

It will be nice allow to explicit extend component's classes via className prop:

<Component className="global-class"/> // <div class="Component global-class"/>

Also, it let's to mix Decss'ed components:

// Inner.js
import {Inner} from './Inner.css'
export default () => <Inner/>

// Wrapper.js
import {Wrapper} from './Wrapper.css'
import {Inner} from './Inner.js'
export default () => (
  <Wrapper tag={Inner} className="global-class"/> // <div class="Wrapper Inner global-class"/>
)

It'll be useful in cases, when the creating of the nested tags is undesirable.

What do you think about it?

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.