npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

morpho

v0.3.0

Published

A tiny CSS-in-JS library using Javascript objects.

Downloads

10

Readme

Morpho

Small and beautiful CSS-in-JS library

Features

  • Tiny - 1.6 kb
  • Framework Agnostic - use with Hyperapp, React, Vue, Angular or anything that has a class attribute
  • Uniquely scoped class names: .morpho-nnbflx
  • Custom css class name prefixing: .article-header-xj38d
  • Custom default numerical units: 5 -> 5em
  • Vendor Prefixing {-webkit-box-direction: normal; box-direction: normal;}
  • List values: [width, 2] -> transition: width 2s;
  • @media queries @media (max-width: 450px){}
  • @keyframes @keyframes morpho-nnbflx {}
  • Nesting .morpho-dx8a25 {} h1 .morpho-dx8a25 {}
  • Dynamic Prop values props => ({color: props.color})
  • Pseudo Selectors and elements .morpho-5tqubj:hover {}
  • Combinators .morpho-ra155c + .morpho-ra155c {}
  • Styled Components styled("div", { borderRadius: "5px" })
    • Style Unstyled Components styled(Button, { color: "tomato" })
    • Extend Styled Components styled(GreenButton, { fontSize: 10 })

Setup

Install morpho library

npm i morpho

With a module bundler like Rollup or Webpack, import morpho into your application

import morpho from "morpho"

If a bundler is not being used, morpho can be imported in a <script> tag as a module.

<script type="module">
  import morpho from "https://unpkg.com//to be determined//"
</script>

Getting Started

const options = {} //See options below

const { css, keyframes } = morpho(options);

const generatedClassName = css({
  color: "blue"
})

//Hyperapp
const Component = (props, children) => {
  return h("div", {class: generatedClassName}, children)
}

//React
const Component = (props) => {
  return <div className={generatedClassName}>Hello World</div>
}

//Vue
<div v-bind:class="[activeClass]"></div>
data: {
  activeClass: generatedClassName,
}

//Angular
<div [ngClass]="{[generatedClassName]: true}">

Options

{
  prefix: "morpho"
  unit: "em",
  cssProps: {
    border: {
      vendor: ["-webkit-", "-moz-"],
      unit: "%"
    }
  }
}
  • prefix - This option is used to specific the global custom prefix for generated css class names. Can be overridden by each css function call css({}, "customPrefix"). Default value is "morpho".

  • unit - This option is used to specify the global default numerical unit. Examples include: "%", "rem", or "px". Default value is "px".

  • cssProps - Use this option to fully customize how each css property will apply vendor prefixing or default numerical values. For example, if you want the css property transition to use the "-webkit-" prefix and a default unit in milliseconds "ms", you would initialize this option to:

    cssProps: {
      transition: {
        vendor: ["-webkit-"], //Accepts and applies a list of vendor prefixes
        unit: "ms" //Appends a unit to a numerical value.  Ex: 5 -> 5ms
      }
    }

    Note: cssProps will override settings from morpho-vendor and morpho-unit

  • Uniquely scoped class names

    .morpho-nnbflx
  • Styled components

    • For any framework that supports JSX or exposes an h() function, you can use the morpho-style library to create styled components
    import { morpho } from "morpho"
    const { css, keyframes } = morpho(options);
    
    import {morphoStyle} from "morpho-style"
    const {styled} = morphoStyle(css, h, styleOptions) //Requires morpho's css function and the JSX h function
      
    const Button = styled("div", {
      margin: "1em",
      padding: "0.25em 1em",
      borderRadius: "3px"
    });
  • Vendor Prefixing

    • If you wish to support vendor prefixing, you can use the morpho-vendor library which has a predefined list of css properties based on data from browserlist and mdn-browser-compat-data
    import { morpho } from "morpho"
    import { vendorProps } from "morpho-vendor"
    
    const { css, keyframes } = morpho({vendorProps});
    
    const vendorClassName = css({
      boxDirection: "normal"
    })
    .morpho-en4vga {
      -webkit-box-direction: normal;
      box-direction: normal;
    }
  • Custom default units

    • If you want morpho to default numerical values with unit, you can use the predefined list from morpho-unit. Note - This list currently only contains css properties that are unitless. The global default will append "px". Todo - Add additional default units to several css properties based on CSS Best Practices
    import { morpho } from "morpho"
    import { unitProps } from "morpho-unit"
    
    const { css, keyframes } = morpho({cssProps: unitProps});
    
    const vendorClassName = css({
      border: 5
    })
    .morpho-en4vga {
     border: 5px;
    }
  • Extend a component

    const GreenButton = styled(Button, {
      color: "tomato",
    });
  • Style an unstyled component

    const Button = (props) => h("div", {class: props.class}, props.children);
    
    const OrangeButton styled(Button, {
      backgroundColor: "orange"
    })
  • Custom class name prefixing

    const Fancy = styled("div", {
        borderRightWidth: 5
    },"article-header")
    
    const className = css({borderRightWidth: 5}, "article-header")
    .article-header-nnbflx
  • Media queries

    @media (max-width: 450px) {
      .morpho-yi32xy {
        font-size: 32px;
      }
    }
  • Keyframes

    keyframes({
      from: {
        transform: 'scale(2)'
      },
      to: {
        transform: 'scale(4)'
      },
    })
    @keyframes morpho-nnbflx {
      from {
        transform: scale(2);
      }
    
      to {
        transform: scale(4);
      }
    }
  • Numeric values

    const Fancy = styled("div", {
      width: 5,
      columns: 10
    })
  • List of values

    const Fancy = styled("div", {
      transition: ["width", 2]
    })
    .morpho-ta4jzb {
      -webkit-transition: width 2s;
      transition: width 2s;
    }
  • Repeat properties using nested arrays

    const Fancy = styled("div", {
      position: [["-webkit-sticky"], ["sticky"]]
    })
    .morpho-ta4jzb {
      position: -webkit-sticky;
      position: sticky;
    }
  • Nesting

    const Fancy = styled("div", {
      width: 5,
      "h1 &": {
        color: "orange",
        tag: {
          fontSize: "21px",
          "& h2": {
            border: "5px"
          }
        }
      }
    })
    .morpho-dx8a25 {width: 5%;}
    h1 .morpho-dx8a25 {color: orange;}
    h1 .morpho-dx8a25 tag {font-size: 21px;}
    h1 .morpho-dx8a25 tag .morpho-dx8a25 h2 {border: 5px;}
  • Dynamically set css values from props

    const Button = styled("div", props => ({
      color: props.myColor || "green",
      width: props.size || "5px"
    }))
    Button({ myColor: "orange", size: "20px" });
    .morpho-qbjka {
      color: orange;
      width: 20px;
    }
  • Pseudo selectors and elements

    const Link = styled("div", {
      color: "blue",
      "&:hover": {
        color: "red"
      }
    })
    .morpho-5tqubj:hover {
      color: red;
    }
    .morpho-5tqubj {
      color: blue;
    }
  • Combinators

    const Fancy = styled("div", {
      color: "#123456",
      "& + &": {
        color: "#32AB71"
      }
    })
    .morpho-ra155c + .morpho-ra155c {
      color: #32AB71;
    }
    .morpho-ra155c {
      color: #123456;
    }

Credits

A lot of inspiration and work for this library comes from Picostyle. Some of the work I added to Picostyle including css export is also found here.

Differences between morpho and picostyle

Morpho adds a lot of additional features that are not found in Picostyle including: list values, default numeric units, vendor prefixing, nesting, and dynamic values from props.