Skip to content

Instantly share code, notes, and snippets.

@bwalex
Last active August 12, 2018 06:03
Show Gist options
  • Save bwalex/75e1cf3a22967f215ed2eddd4336cf35 to your computer and use it in GitHub Desktop.
Save bwalex/75e1cf3a22967f215ed2eddd4336cf35 to your computer and use it in GitHub Desktop.
emotion css with clojurescript. see https://github.com/bwalex/verktyg for a better implementation
(ns dlt.styled.core
(:require [clojure.string]
[create-emotion :as createEmotion]))
(defonce emotion
(createEmotion #js {}))
;; from filter-react-dom-props
(def dom-props
[:abbr
:accept
:accept-charset
:access-key
:action
:allow-full-screen
:allow-transparency
:alt
:async
:auto-complete
:auto-focus
:auto-play
:cell-padding
:cell-spacing
:challenge
:charset
:checked
:cite
:class
:class-name
:cols
:col-span
:command
:content
:content-editable
:context-menu
:controls
:coords
:cross-origin
:data
:date-time
:default
:defer
:dir
:disabled
:download
:draggable
:dropzone
:enc-type
:for
:form
:form-action
:form-enc-type
:form-method
:form-no-validate
:form-target
:frame-border
:headers
:height
:hidden
:high
:href
:href-lang
:html-for
:http-equiv
:icon
:id
:input-mode
:is-map
:item-id
:item-prop
:item-ref
:item-scope
:item-type
:key
:kind
:label
:lang
:list
:loop
:manifest
:max
:max-length
:media
:media-group
:method
:min
:min-length
:multiple
:muted
:name
:no-validate
:open
:optimum
:pattern
:ping
:placeholder
:poster
:preload
:radio-group
:read-only
:rel
:required
:role
:rows
:row-span
:sandbox
:scope
:scoped
:scrolling
:seamless
:selected
:shape
:size
:sizes
:sortable
:span
:spell-check
:src
:src-doc
:src-set
:start
:step
:style
:tab-index
:target
:title
:translate
:type
:type-must-match
:use-map
:value
:width
:wmode
:wrap
:on-copy
:on-cut
:on-paste
:on-load
:on-error
:on-wheel
:on-scroll
:on-composition-end
:on-composition-start
:on-composition-update
:on-key-down
:on-key-press
:on-key-up
:on-focus
:on-blur
:on-change
:on-input
:on-submit
:on-click
:on-context-menu
:on-double-click
:on-drag
:on-drag-end
:on-drag-enter
:on-drag-exit
:on-drag-leave
:on-drag-over
:on-drag-start
:on-drop
:on-mouse-down
:on-mouse-enter
:on-mouse-leave
:on-mouse-move
:on-mouse-out
:on-mouse-over
:on-mouse-up
:on-select
:on-touch-cancel
:on-touch-end
:on-touch-move
:on-touch-start
:on-animation-start
:on-animation-end
:on-animation-iteration
:on-transition-end])
(defn filter-props [props]
(select-keys props dom-props))
(defn -css-str [call-args part]
{:pre [(or (string? part)
(fn? part))]}
(if (fn? part)
(apply part call-args)
part))
(defn make-emotion-fn [css-fn parts]
{:pre [(coll? parts)
(fn? css-fn)]}
(fn [& args]
(let [style (reduce #(str %1 (-css-str args %2)) "" parts)]
(css-fn style))))
(defn css [& parts]
(make-emotion-fn (.-css emotion) parts))
(defn inject-global [& parts]
(make-emotion-fn (.-injectGlobal emotion) parts))
(defn styled [c & style-parts]
(let [class-fn (apply css style-parts)]
(fn [props & children]
(let [class-name (str (get props :class "") " " (class-fn props))
new-props (assoc props :class class-name)
filt-props (if (keyword? c)
(filter-props new-props)
new-props)]
(into [c filt-props] children)))))
(ns dlt.styled.macros
(:require [clojure.string]))
;; from roman01la/cljss
(defmacro var->cmp-name [sym]
`(-> ~'&env :ns :name (clojure.core/str "." ~sym)))
(defmacro defstyled [var tag & style-parts]
(let [cmp-name# (var->cmp-name var)
parts# (into [] style-parts)]
`(def ~var
(reagent.core/create-class
{:display-name ~cmp-name#
:reagent-render (fn [props# & children#]
(let [css-fn# (apply dlt.styled.core/css ~parts#)
cls-names# (str (get props# :class "") " " (css-fn# props#))
new-props# (merge props# {:class cls-names#})
filt-props# (if (keyword? ~tag)
(dlt.styled.core/filter-props new-props#)
new-props#)]
(into [~tag filt-props#] children#)))}))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment