-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor to support a dynamic "style container" to render CSS into
See #12
- Loading branch information
Showing
11 changed files
with
163 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
(ns spade.runtime | ||
(:require [clojure.string :as str] | ||
[garden.core :as garden] | ||
[garden.types :refer [->CSSFunction]] | ||
[spade.runtime.shared :as container] | ||
[spade.runtime.defaults :as defaults])) | ||
|
||
(defonce ^:dynamic *css-compile-flags* | ||
{:pretty-print? #? (:cljs goog.DEBUG | ||
:clj false)}) | ||
|
||
(defonce ^:dynamic *style-container* (defaults/create-container)) | ||
|
||
(defn ->css-var [n] | ||
(->CSSFunction "var" n)) | ||
|
||
(defn compile-css [elements] | ||
(garden/css *css-compile-flags* elements)) | ||
|
||
(defn- compose-names [{style-name :name composed :composes}] | ||
(if-not composed | ||
style-name | ||
(str/join " " | ||
(->> | ||
(if (seq? composed) | ||
(into composed style-name) | ||
[composed style-name]) | ||
(map (fn [item] | ||
(cond | ||
(string? item) item | ||
|
||
; unpack a defattrs | ||
(and (map? item) | ||
(string? (:class item))) | ||
(:class item) | ||
|
||
:else | ||
(throw (ex-info | ||
(str "Invalid argument to :composes key:" | ||
item) | ||
{}))))))))) | ||
|
||
(defn ensure-style! [mode base-style-name factory params] | ||
(let [{css :css style-name :name :as info} (apply factory base-style-name params params)] | ||
|
||
(container/mount-style! *style-container* style-name css) | ||
|
||
(case mode | ||
:attrs {:class (compose-names info)} | ||
(:class :keyframes) (compose-names info) | ||
:global css))) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
(ns spade.runtime.atom | ||
(:require [spade.runtime.shared :refer [IStyleContainer]])) | ||
|
||
(deftype AtomStyleContainer [styles-atom] | ||
IStyleContainer | ||
(mount-style! [_ style-name css] | ||
(swap! styles-atom assoc style-name css))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(ns spade.runtime.defaults | ||
(:require [spade.runtime.atom :refer [->AtomStyleContainer]])) | ||
|
||
(defonce shared-styles-atom (atom nil)) | ||
|
||
(defn create-container [] | ||
(->AtomStyleContainer shared-styles-atom)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
(ns spade.runtime.defaults | ||
(:require [spade.runtime.dom :as dom])) | ||
|
||
(defn create-container [] | ||
(dom/create-container)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
(ns spade.runtime.dom | ||
(:require [spade.runtime.shared :as container :refer [IStyleContainer]])) | ||
|
||
(defonce ^:dynamic *injected-styles* (atom nil)) | ||
(defonce ^:dynamic *dom* nil) | ||
|
||
(defn- perform-update! [obj css] | ||
(set! (.-innerHTML (:element obj)) css)) | ||
|
||
(defn update! [styles-container id css] | ||
(swap! styles-container update id | ||
(fn update-injected-style [obj] | ||
(when-not (= (:source obj) css) | ||
(perform-update! obj css)) | ||
(assoc obj :source css)))) | ||
|
||
(defn inject! [target-dom styles-container id css] | ||
(let [destination (or (when (ifn? target-dom) | ||
(target-dom)) | ||
target-dom | ||
(.-head js/document)) | ||
element (doto (js/document.createElement "style") | ||
(.setAttribute "spade-id" (str id))) | ||
obj {:element element | ||
:source css | ||
:id id}] | ||
(assert (some? destination) | ||
"An <head> element or target *dom* is required to inject the style.") | ||
|
||
(.appendChild destination element) | ||
|
||
(swap! styles-container assoc id obj) | ||
(perform-update! obj css))) | ||
|
||
(deftype DomStyleContainer [target-dom styles-container] | ||
IStyleContainer | ||
(mount-style! [_ style-name css] | ||
(let [resolved-container (or styles-container | ||
*injected-styles*)] | ||
(if (contains? @resolved-container style-name) | ||
(update! resolved-container style-name css) | ||
(inject! target-dom resolved-container style-name css))))) | ||
|
||
(defn create-container | ||
([] (create-container nil)) | ||
([target-dom] (create-container target-dom (when target-dom | ||
(atom nil)))) | ||
([target-dom styles-container] | ||
(->DomStyleContainer target-dom styles-container))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(ns spade.runtime.shared) | ||
|
||
(defprotocol IStyleContainer | ||
(mount-style! | ||
[this style-name css] | ||
"Ensure the style with the given name and CSS is available")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
(ns spade.jvm-test | ||
(:require [clojure.test :refer [deftest is testing]] | ||
[spade.runtime.defaults :refer [->AtomStyleContainer]] | ||
[spade.runtime] | ||
[spade.core :refer [defclass with-styles-container]])) | ||
|
||
(defclass blue-class [] | ||
{:color "blue"}) | ||
|
||
(deftest with-styles-container-test | ||
(testing "Render styles to dynamically-provided Atom container" | ||
(let [styles (atom nil) | ||
container (->AtomStyleContainer styles) | ||
style-name (with-styles-container container | ||
(blue-class))] | ||
(is (= "blue-class" style-name)) | ||
(is (= ".blue-class{color:blue}" | ||
(get @styles style-name)))))) | ||
|