-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
core.cljc
81 lines (73 loc) · 3.34 KB
/
core.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
(ns girouette.tw.core
(:require
[clojure.string :as str]
[instaparse.core :as insta]
[girouette.util :as util]
[girouette.tw.common :as common]
[girouette.tw.color :as color]
[girouette.tw.typography :as typography]))
(defn- assemble-grammar [components {:keys [color-map font-family-map]}]
(let [root-rule (str "css-class = prefixes ("
(->> components
(map (comp name :id))
(str/join " | "))
")\n")]
(->> (concat
[root-rule]
(map :rules components)
[common/common-rules
(color/color-rules color-map)
(typography/font-family-rules font-family-map)])
(apply str))))
(defn- parsed-data->props [class-name parsed-data predef-props]
(let [[_
[_ & prefixes]
[component-id & component-data]] parsed-data
{[media-query-min-width] :media-query-min-width
[media-query-color-scheme] :media-query-color-scheme
[media-query-reduced-motion] :media-query-reduced-motion
state-variants :state-variant} (util/group-by first second prefixes)]
(assoc predef-props
:class-name class-name
:prefixes {:media-query-min-width media-query-min-width
:media-query-color-scheme media-query-color-scheme
:media-query-reduced-motion media-query-reduced-motion
:state-variants state-variants}
:component-id component-id
:component-data (vec component-data))))
(defn- pipeline->transform [pipeline]
(fn [rule props]
(reduce (fn [rule f] (f rule props))
rule
(->> pipeline
((juxt :media-queries
:outer-state-variants
:class-name
:inner-state-variants))
(apply concat)
reverse))))
(defn make-api
"Creates an API based on a collection of Girouette components."
[components {:keys [color-map font-family-map] :as options}]
(let [components (util/into-one-vector components) ;; flatten the structure
grammar (assemble-grammar components options)
parser (insta/parser grammar)
component-by-id (into {}
(map (juxt :id identity))
components)
predef-props {:read-color (partial color/read-color color-map)
:font-family-map font-family-map}
class-name->garden (fn [class-name]
(let [parsed-data (insta/parse parser class-name)]
(when-not (insta/failure? parsed-data)
(let [props (parsed-data->props class-name parsed-data predef-props)
component (component-by-id (:component-id props))
garden-fn (:garden component)
pipeline (:pipeline component common/default-pipeline)
transform (pipeline->transform pipeline)]
(-> (garden-fn props)
(transform props))))))]
{:grammar grammar
:parser parser
:component-by-id component-by-id
:class-name->garden class-name->garden}))