Coder Social home page Coder Social logo

cdonohue / benefit Goto Github PK

View Code? Open in Web Editor NEW
51.0 4.0 5.0 5.31 MB

✨ Utility CSS-in-JS library that provides a set of low-level, configurable, ready-to-use styles

Home Page: https://benefit.netlify.com

License: MIT License

JavaScript 62.10% TypeScript 36.49% CSS 1.10% HTML 0.31%
css-in-js utility-classes emotion tailwindcss jsx design system css

benefit's Introduction

Benefit Logo


Style web applications using generated utility classes

benefit is a utility CSS-in-JS library that provides a set of low-level, configurable, ready-to-use styles.

Documentation

benefit is framework agnostic, use benefit-react for additional enhancements for React.


React-specific

Install dependencies

Add benefit-react to your project.

yarn add benefit-react

Setup transpilation

Set the jsx pragma at the top of your source file where you intend to use benefit-react.

Similar to a comment containing linter configuration, this configures the jsx babel plugin to use the jsx function instead of React.createElement.

JSX Pragma Documentation

Import the jsx function from benefit-react

/** @jsx jsx */
import { jsx } from "benefit-react"

Now, you're free to use any available utility classes to style your components

/** @jsx jsx */
import { jsx } from "benefit-react"

function MyComponent() {
  return (
    <div className="p-4 bg-orange-300 rounded">
      <p className="p-4 bg-white shadow rounded-sm">
        Williamsburg stumptown iPhone, gastropub vegan banh mi
        microdosingpost-ironic pok pok +1 bespoke dreamcatcher bushwick brunch.
      </p>
    </div>
  )
}

Framework agnostic

Add benefit to your project.

yarn add benefit

Import and use the createBenefit function to create your utility classes

import { createBenefit } from "benefit"

const { styleWith } = createBenefit()

Use styleWith(...) to pass in utility classes

<div class={styleWith("p-4 bg-white text-blue-700")}>
  ...
</div>

benefit's People

Contributors

cdonohue avatar ericclemmons avatar gastonfartek 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

Watchers

 avatar  avatar  avatar  avatar

benefit's Issues

Align behavior of React and vanilla styling results

Using styleWith currently adds individual utility styles as separate style tags to try and reduce duplication. However, this can lead to unwanted results since the last style declared will always win.

Example:

<div className="p-8 text-center bg-red-500 lg:bg-red-500 mt-2 text-white rounded">
  I'm Red
</div>
<div className="p-8 text-center bg-blue-500 md:bg-yellow-500 lg:bg-red-500 text-white rounded">
  I Should Be Red on Large Screens
</div>

Here, since lg:bg-red-500 is declared by the first div, it will come before md:bg-yellow-500, wich is inserted last. The final div should be red per the media query class applied (lg:bg-red-500).

The React implementation does this via the css prop to combine all related styles into one uniquely hashed selector class.

getDeclarationsForClasses not defined in benefit-react v2

How would I go about writing this code using benefit 1.1.1 into benefit-react@latest ?

I noticed that the ConfigConsumer no longer provides the getDeclarationsForClasses method but instead exposes a styleWith that uses it under the hood, but not sure how to translate the below use case into styleWith

any help much appreciated 👍

import { css as processCss, jsx } from "@emotion/core"
import { ConfigConsumer } from "benefit-react"

function MyComponent({children, ...remainingProps}) {

    const { declarations, ignoredClasses } = getDeclarationsForClasses(
         className,
         important
     )
    
     const processedDeclarations = declarations.map(
         (declaration) => processCss`${declaration}`
     )

     if (css) {
        processedDeclarations.push(css)
      }

       remainingProps.css = processedDeclarations
       remainingProps.className = ignoredClasses.join(" ")

       return jsx(is, remainingProps, ...children)
}

Don't `normalize` by default

Maybe setting normalize styles on every touched element is a bit too aggressive. I'm thinking there are two use cases here:

  • Return a function from benefit() that allows for the user to injectGlobal and have access to the theme values.

  • Have a normalize option to pass into the styleWith function for one-offs

Use `rollup`

We need a vanilla benefit require as well as the ability to require from benefit/react as a separate file to get react helpers from.

Example:

import { benefit } from "benefit"

-or-

import { jsx } from "benefit/react"

To support different input/output files, I'm going to experiment with using rollup in place of microbundle

https://github.com/rollup/rollup

Make preflight more declarative

Instead of requiring an injectPreflight boolean to the config, just make it available to the dev/user.

benefit-react would use something like <Preflight />

SSR support

Server rendering (inline styles) should be supported in benefit-react out of the box and possibly configurable using benefit with a few additional steps.

Initially, this needs to work with

  • Gatsby
  • Next

htm support

In #16, I found that it's pretty trivial to automatically instrument https://github.com/developit/htm's vdom output to use benefit.

The rough code is:

  import { html, render } from 'https://unpkg.com/htm/preact/standalone.mjs';

  const { cx } = benefit()

  // ! TODO Make this a utility of benefit
  const styleWithHtml = (...args) => {
    const vdom = html(...args);

    (function replaceClassWithBenefit(vdom) {
      if (vdom.attributes && vdom.attributes.class) {
        vdom.attributes.class = cx(vdom.attributes.class)
      }

      if (vdom.children) {
        vdom.children.forEach((child) => replaceClassWithBenefit(child))
      }
    })(vdom);

    return vdom
  }

  const vdom = styleWithHtml`
    <main class="antialiased">Howdy</main>
  `

  render(vdom, document.body)

```

Obviously, what we'd like to do is have a wrapper kinda like:

```
import { html, render } from 'https://unpkg.com/htm/preact/standalone.mjs';
const { styleWithHtml } = benefit()

const styled = styleWithHtml(html)

const vdom = styled`...`
```

Opt-in to preflight styles

Currently, preflight global styles are injected as a sensible default to an app-level styling approach.

This is a bit aggressive and could be more useful if it could be added by the developer.

benefit

named export from package, like injectPreflight or similar

benefit-react

<Preflight /> component

Keep classNames the same?

When developing, as a utility CSS library, seeing the original classNames (e.g. m-1, rounded, etc.) when inspecting the output is helpful for validation.

There are some important things to note about this, though:

This may be a non-issue, or something to think about at another time.

But I found it somewhat interesting when authoring and then inspecting the HTML and seeing hashed names.

Add in support for element normalization

Add in a normalize property to the benefit configuration that would allow for resetting of styles at an element level.

I think of this as a CSS Reset at the element level ( like margin: 0, padding: 0, etc )

Make live code examples in docs

The CodeBlock component in the benefit-docs codebase has support for passing live as a boolean prop. We should incorporate these into the utility examples as a way to let the user change code directly on the page.

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.