Giter VIP home page Giter VIP logo

style-plus's Introduction

 

Locate your styles.

Style-plus enables co-location of styles within ClojureScript Reagent components.

The library provides a thin syntactical abstraction over the excellent Stylefy library, as well as some additional css helper functions.

The motivation behind style-plus is to completely eliminate the need to write and maintain separate style sheets for projects targeting browser environments.

 

Status

Currently in maintenance mode. This project ended up becoming a precursor to Kushi, which is a much more complete and robust solution. If you are starting a new project, you should use Kushi instead of this.

 

Usage

First, add the dependency to your project:

[paintparty/style-plus "0.5.0-SNAPSHOT"]

 

Then, follow the Setup Instructions for Stylefy.

 

Lastly, require style-plus into the namespace(s) as needed:

(:require [style-plus.core :as style-plus :refer [s+]])

 

Now, you can style your components w the following features:

  1. Media queries and pseudo-classes at a property-level
  2. The same implicit integer-to-pixel convention that Reagent uses
  3. Garden syntax (Stylefy uses garden under the hood), such as [[10 20]]
  4. Optionally attach a ns-qualifed custom data attribute.

 

The s+ function takes a map of styles, and an optional map of html attributes. Media-queries are expressed as maps, while psuedo-classes are expressed as strings. A key of := represents the default value.

(defn button [label]
  [:div
    (s+ {:cursor :pointer
         :text-align :center
         :padding [[10 20]]
         :color {:= :blue
                 "hover" :red}
         :font-size {:= 18
                     {:max-width 500} 16
                     {:max-width 700} 20}}
         :border {:= [[1 :solid :blue]]
                  "hover" [[1 :solid :red]]}
        {:role :button
         :on-click #()})
    label])

 

With the above example, Stylefy automatically injects the following selectors into your document, as well attaching the appropriate class names to the element in your component:

._stylefy_1838088000 {
    border: 1px solid blue;
    padding: 10px 20px;
    text-align: center;
    cursor: pointer;
    font-size: 18px;
    color: blue;
}
._stylefy_1838088000:hover {
    color: red;
    border: 1px solid red;
}

 

 

Helpers

style-plus ships with 3 helper functions for defining css breakpoints.

In the example below, a number of global breakpoints are defined in a dedicated namespace.

(ns my-project.breakpoints
  (:require [style-plus.core :refer [above below between]]))

;; Define some breakpoints
(def bp
 {:sm 576
  :md 768
  :lg 992
  :xl 1200})

;; If you are designing for laptop/desktop
;; (below :sm bp) => {:max-width 575.98px}
(def sm (below :sm bp))
(def md (below :md bp))
(def lg (below :lg bp))
(def xl (below :xl bp))
(def md-only (between :sm :md bp))
(def md-xl (between :md :xl bp))

;; If you are designing for mobile-first
;; (below :sm bp) => {:min-width 576px}
; (def sm (above :sm bp))
; (def md (above :md bp))
; (def lg (above :lg bp))
; (def xl (above :xl bp))
; (def md-only (between :sm :md bp))
; (def md-xl (between :md :xl bp))

 

These breakpoint defs can then be used with style-plus.

(ns my-project.ui
  (:require [my-project.breakpoints :refer [sm lg]]))

(defn header [text]
  [:h1
    (s+ {:font-size {:= 18 sm 16 lg 24}})
    text])

 

 

Using Metadata

Co-locating your style inside components obviates the need to use class names and css selectors. The html generated in the DOM will have many auto-generated class names (like the ones above), and possibly some utility classes, if you are using an atomic css library. As a result, it can become difficult to quickly comprehend the source location when looking at elements in a browser inspector (such as Chrome DevTool Elements panel).

With s+, you can add metadata to the style-map (first arg), which will then be transformed into a unique value and attached to the element as a custom data attribute called data-ns. This metadata should be a map with single entry. The key is the var-quoted function name and the value is a user-defined keyword (which should have some kind of symantic relationship to the actual element).

(ns my-project.ui
  (:require [style-plus.core :refer [s+]]))


(defn my-button [label]
  (let [f #'my-button]
    [:div
     (s+ ^{#'f :outer}
         {:cursor :pointer
          :text-align :center
          :border [[1 :solid :blue]]}
         {:role :button
          :on-click #()})
     [:span
      (s+ ^{#'f :inner}
          {:background :yellow})
      label]])

In resulting html (from a call such as [my-button "Go"]) the namespace, function, element-name, and source line number are clearly evident:

<div class="_stylefy_-545329968"
     data-ns="my-project.ui/my-button::outer:619"
     role="button" >
  <div data-ns="my-project.ui/my-button::inner:619"
       class="_stylefy_457554977">Go</div>
</div>

If want to attach the identifying custom-data attribute manually, or use a different key than the default :data-ns(:data-foo is used in the example below), you can make use of style-plus/ns+:

;; Require it into your namespace
(ns my-project.ui
  (:require [style-plus.core :refer [s+ ns+]]))


;; Use ns+ in the html attributes map
(defn my-button [label]
  [:div
  (s+ {:cursor :pointer
       :text-align :center
       :border [[1 :solid :blue]}
      {:role :button
       :on-click #()
       :data-foo (ns+ #'my-button :outer)})
    [:span
      (s+ {:background :yellow}
          {:data-foo (ns+ #'my-button :inner})
      label]])

The second keyword argument to ns+ is optional. You can also call it like this:

(ns+ #'my-button)
;; => "my-project.ui/my-button:619"

License

Copyright © 2020 JC

This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.

This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.

style-plus's People

Contributors

paintparty avatar

Stargazers

Cort Spellman avatar  avatar Léon Talbot avatar

Watchers

Léon Talbot avatar  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.