/
util.cljc
82 lines (72 loc) · 2.1 KB
/
util.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
82
(ns daiquiri.util
(:require [clojure.set :refer [rename-keys]]
[clojure.string :as str]))
(defn valid-key? [k]
(or (keyword? k)
(string? k)
(symbol? k)))
(defn -camel-case [k]
(if (string? k)
k
(let [[first-word & words] (.split (name k) "-")]
(if (or (empty? words)
(= "aria" first-word)
(= "data" first-word))
k
(-> (map str/capitalize words)
(conj first-word)
str/join
keyword)))))
(def attrs-cache (volatile! {}))
(defn camel-case
"Returns camel case version of the key, e.g. :http-equiv becomes :httpEquiv.
Does not convert string attributes."
[k]
(if (valid-key? k)
(or (get @attrs-cache k)
(let [kk (-camel-case k)]
(vswap! attrs-cache assoc k kk)
kk))
k))
(defn camel-case-keys* [m]
(->> (reduce-kv #(assoc! %1 (camel-case %2) %3)
(transient {})
m)
persistent!))
(defn camel-case-keys
"Recursively transforms all map keys into camel case."
[m]
(if (map? m)
(let [m (->> m
(reduce-kv #(assoc! %1 (camel-case %2) %3)
(transient {}))
persistent!)]
(cond-> m
(map? (:style m))
(update :style camel-case-keys)))
m))
(defn fragment?
"Returns true if `tag` is the fragment tag \"*\" or \"<>\", otherwise false."
[tag]
(or (= (name tag) "*")
(= (name tag) "<>")))
(defn element?
"Return true if `x` is an HTML element. True when `x` is a vector
and the first element is a keyword, e.g. `[:div]` or `[:div [:span \"x\"]`."
[x]
(and (vector? x)
(keyword? (nth x 0 nil))))
(defn html-to-dom-attrs
"Converts all HTML attributes to their DOM equivalents."
[attrs]
(rename-keys (camel-case-keys attrs)
{:class :className
:for :htmlFor}))
(defn join-classes
"Join the `classes` with a whitespace."
[classes]
(->> classes
(into [] (comp
(mapcat (fn [x] (if (string? x) [x] (seq x))))
(remove nil?)))
(str/join " ")))