Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameters to defkeyframes #5

Merged
merged 2 commits into from
Aug 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Spade supports `@media` queries in the exact same way you see them in the [garde
Spade even supports generating `@keyframes` just like you'd expect:

```clojure
(defkeyframes anim-frames
(defkeyframes anim-frames []
["0%" {:opacity 0}]
["100%" {:opacity 1}])
```
Expand Down
8 changes: 6 additions & 2 deletions dev/spade/demo.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
[reagent.core :as r]
[spade.core :refer [defclass defattrs defglobal defkeyframes]]))

(defkeyframes anim-frames
(defkeyframes anim-frames []
["0%" {:opacity 0}]
["100%" {:opacity 1}])

(defkeyframes parameterized-anim-frames [start end]
["0%" {:opacity start}]
["100%" {:opacity end}])

(defglobal background
[:body {:background "#333"}])

Expand All @@ -19,7 +23,7 @@
{:padding "8px"}

[:.title {:font-size "22pt"
:animation [[(anim-frames) "560ms" 'ease-in-out]]}])
:animation [[(parameterized-anim-frames 0 0.5) "560ms" 'ease-in-out]]}])

(defclass colorized-with-key [color]
^{:key (str/upper-case color)}
Expand Down
96 changes: 62 additions & 34 deletions src/spade/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -51,54 +51,82 @@
(assoc base :composes composition)
base)))

(defn- transform-named-style [style style-name-var params-var]
(defn- build-style-naming-let
[style params original-style-name-var params-var]
(let [has-key-meta? (find-key-meta style)
static-key (extract-key style)
[composition style] (extract-composes style)
name-var (gensym "name")
style-var (gensym "style")]
(if (or static-key
(not has-key-meta?))
name-var (gensym "name")]
(cond
; easiest case: no params? no need to call build-style-name
(nil? (seq params))
[nil original-style-name-var nil]

(or static-key
(not has-key-meta?))
; if we can extract the key statically, that's better
(let [name-creator `(#'build-style-name
~style-name-var
~static-key
~params-var)]
`(let [~name-var ~name-creator
~style-var ~(into [`(str "." ~name-var)] style)]
~(with-composition composition name-var style-var)))

`(let [base-style# ~(vec style)
key# (:key (meta (first base-style#)))
~name-var (#'build-style-name
~style-name-var
key#
~params-var)
~style-var (into [(str "." ~name-var)] base-style#)]
~(with-composition composition name-var style-var)))))

(defn- transform-style [mode style style-name-var params-var]
[nil name-var `[~name-var (#'build-style-name
~original-style-name-var
~static-key
~params-var)]]

:else
(let [base-style-var (gensym "base-style")]
[base-style-var name-var `[~base-style-var ~(vec style)
key# (:key (meta (first ~base-style-var)))
~name-var (#'build-style-name
~original-style-name-var
key#
~params-var)]]))))

(defn- transform-named-style [style params style-name-var params-var]
(let [[composition style] (extract-composes style)
style-var (gensym "style")
[base-style-var name-var name-let] (build-style-naming-let
style params style-name-var
params-var)
style-decl (if base-style-var
`(into [(str "." ~name-var)] ~base-style-var)
(into [`(str "." ~name-var)] style))]
`(let ~(vec (concat name-let
[style-var style-decl]))
~(with-composition composition name-var style-var))))

(defn- transform-keyframes-style [style params style-name-var params-var]
(let [[style-var name-var style-naming-let] (build-style-naming-let
style params style-name-var
params-var)
info-map `{:css (spade.runtime/compile-css
(garden.stylesheet/at-keyframes
~name-var
~(or style-var
(vec style))))
:name ~name-var}]

; this (let) might get compiled out in advanced mode anyway, but
; let's just generate simpler code instead of having a redundant
; (let) if the keyframes take no params
(if style-naming-let
`(let ~style-naming-let ~info-map)
info-map)))

(defn- transform-style [mode style params style-name-var params-var]
(let [style (replace-at-forms style)]
(cond
(#{:global} mode)
`{:css (spade.runtime/compile-css ~(vec style))
:name ~style-name-var}

; keyframes are a bit of a special case
(#{:keyframes} mode)
`{:css (spade.runtime/compile-css
(garden.stylesheet/at-keyframes
~style-name-var
~(vec style)))
:name ~style-name-var}
(transform-keyframes-style style params style-name-var params-var)

:else
(transform-named-style style style-name-var params-var))))
(transform-named-style style params style-name-var params-var))))

(defmulti ^:private declare-style
(fn [mode _class-name params _factory-name-var _factory-fn-name]
(case mode
:global :static
:keyframes :no-args
(cond
(some #{'&} params) :variadic
(every? symbol? params) :default
Expand Down Expand Up @@ -166,7 +194,7 @@
factory-name-var (gensym "factory-name")]
`(do
(defn ~factory-fn-name ~factory-params
~(transform-style mode style style-name-var params-var))
~(transform-style mode style params style-name-var params-var))

(let [~factory-name-var (factory->name ~factory-fn-name)]
~(declare-style mode class-name params factory-name-var factory-fn-name)))))
Expand All @@ -180,5 +208,5 @@
(defmacro defglobal [group-name & style]
(declare-style-fns :global group-name nil style))

(defmacro defkeyframes [keyframes-name & style]
(declare-style-fns :keyframes keyframes-name nil style))
(defmacro defkeyframes [keyframes-name params & style]
(declare-style-fns :keyframes keyframes-name params style))
12 changes: 10 additions & 2 deletions test/spade/core_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,22 @@
"@media (min-width: 42px) {"))))


(defkeyframes key-frames
(defkeyframes key-frames []
[:from {:opacity 0}])

(defkeyframes parameterized-key-frames [from]
[:from {:opacity from}])

(deftest defkeyframes-test
(testing "Return keyframes name from defkeyframes"
(is (fn? key-frames))
(is (= "spade-core-test-key-frames"
(key-frames)))))
(key-frames))))

(testing "Return dynamic keyframes name from parameterized defkeyframes"
(is (fn? key-frames))
(is (= (str "spade-core-test-parameterized-key-frames_" (hash [0]))
(parameterized-key-frames 0)))))

(defclass composed [color]
^{:key color}
Expand Down