mirror of
https://github.com/penpot/penpot.git
synced 2025-03-12 15:51:37 -05:00
⚡ Add CSS cursor classes
This commit is contained in:
parent
0682ed101d
commit
216454f66f
12 changed files with 136 additions and 50 deletions
|
@ -18,6 +18,7 @@
|
||||||
[app.main.ui :as ui]
|
[app.main.ui :as ui]
|
||||||
[app.main.ui.alert]
|
[app.main.ui.alert]
|
||||||
[app.main.ui.confirm]
|
[app.main.ui.confirm]
|
||||||
|
[app.main.ui.cursors :as cursors]
|
||||||
[app.main.ui.delete-shared]
|
[app.main.ui.delete-shared]
|
||||||
[app.main.ui.modal :refer [modal]]
|
[app.main.ui.modal :refer [modal]]
|
||||||
[app.main.ui.routes :as rt]
|
[app.main.ui.routes :as rt]
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
|
|
||||||
(defn init-ui
|
(defn init-ui
|
||||||
[]
|
[]
|
||||||
|
(cursors/init-styles)
|
||||||
(mf/mount (mf/element ui/app) (dom/get-element "app"))
|
(mf/mount (mf/element ui/app) (dom/get-element "app"))
|
||||||
(mf/mount (mf/element modal) (dom/get-element "modal")))
|
(mf/mount (mf/element modal) (dom/get-element "modal")))
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
(ns app.main.ui.cursors
|
(ns app.main.ui.cursors
|
||||||
(:require-macros [app.main.ui.cursors :refer [cursor-ref cursor-fn]])
|
(:require-macros [app.main.ui.cursors :refer [cursor-ref cursor-fn]])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.util.css :as css]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
@ -51,6 +53,63 @@
|
||||||
(def resize-ew-2 (cursor-fn :resize-h-2 0))
|
(def resize-ew-2 (cursor-fn :resize-h-2 0))
|
||||||
(def resize-ns-2 (cursor-fn :resize-h-2 90))
|
(def resize-ns-2 (cursor-fn :resize-h-2 90))
|
||||||
|
|
||||||
|
(defn get-static
|
||||||
|
[name]
|
||||||
|
(dm/str "cursor-" name))
|
||||||
|
|
||||||
|
(defn get-dynamic
|
||||||
|
[name rotation]
|
||||||
|
(dm/str "cursor-" name "-" (.floor js/Math rotation)))
|
||||||
|
|
||||||
|
(defn init-static-cursor-style
|
||||||
|
[style name value]
|
||||||
|
(.add style (dm/str ".cursor-" name) (js-obj "cursor" (dm/str value " !important"))))
|
||||||
|
|
||||||
|
(defn init-dynamic-cursor-style
|
||||||
|
[style name fn]
|
||||||
|
(let [rotations (seq (range 0 360 1))]
|
||||||
|
(doseq [rotation rotations]
|
||||||
|
(.add style (dm/str ".cursor-" name "-" rotation) (js-obj "cursor" (dm/str (fn rotation) " !important"))))))
|
||||||
|
|
||||||
|
(defn init-styles
|
||||||
|
[]
|
||||||
|
(let [style (css/create-style)]
|
||||||
|
;; static
|
||||||
|
(init-static-cursor-style style "comments" comments)
|
||||||
|
(init-static-cursor-style style "create-artboard" create-artboard)
|
||||||
|
(init-static-cursor-style style "create-ellipse" create-ellipse)
|
||||||
|
(init-static-cursor-style style "create-polygon" create-polygon)
|
||||||
|
(init-static-cursor-style style "create-rectangle" create-rectangle)
|
||||||
|
(init-static-cursor-style style "create-shape" create-shape)
|
||||||
|
(init-static-cursor-style style "duplicate" duplicate)
|
||||||
|
(init-static-cursor-style style "hand" hand)
|
||||||
|
(init-static-cursor-style style "move-pointer" move-pointer)
|
||||||
|
(init-static-cursor-style style "pen" pen)
|
||||||
|
(init-static-cursor-style style "pen-node" pen-node)
|
||||||
|
(init-static-cursor-style style "pencil" pencil)
|
||||||
|
(init-static-cursor-style style "picker" picker)
|
||||||
|
(init-static-cursor-style style "pointer-inner" pointer-inner)
|
||||||
|
(init-static-cursor-style style "pointer-move" pointer-move)
|
||||||
|
(init-static-cursor-style style "pointer-node" pointer-node)
|
||||||
|
(init-static-cursor-style style "resize-alt" resize-alt)
|
||||||
|
(init-static-cursor-style style "zoom" zoom)
|
||||||
|
(init-static-cursor-style style "zoom-in" zoom-in)
|
||||||
|
(init-static-cursor-style style "zoom-out" zoom-out)
|
||||||
|
|
||||||
|
;; dynamic
|
||||||
|
(init-dynamic-cursor-style style "resize-ew" resize-ew)
|
||||||
|
(init-dynamic-cursor-style style "resize-nesw" resize-nesw)
|
||||||
|
(init-dynamic-cursor-style style "resize-ns" resize-ns)
|
||||||
|
(init-dynamic-cursor-style style "resize-nwse" resize-nwse)
|
||||||
|
(init-dynamic-cursor-style style "rotate" rotate)
|
||||||
|
(init-dynamic-cursor-style style "text" text)
|
||||||
|
(init-dynamic-cursor-style style "scale-ew" scale-ew)
|
||||||
|
(init-dynamic-cursor-style style "scale-nesw" scale-nesw)
|
||||||
|
(init-dynamic-cursor-style style "scale-ns" scale-ns)
|
||||||
|
(init-dynamic-cursor-style style "scale-nwse" scale-nwse)
|
||||||
|
(init-dynamic-cursor-style style "resize-ew-2" resize-ew-2)
|
||||||
|
(init-dynamic-cursor-style style "resize-ns-2" resize-ns-2)))
|
||||||
|
|
||||||
(mf/defc debug-preview
|
(mf/defc debug-preview
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -358,9 +358,9 @@
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
|
:class (when (or hover? selected?)
|
||||||
|
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||||
:style {:fill (if (or hover? selected?) distance-color "none")
|
:style {:fill (if (or hover? selected?) distance-color "none")
|
||||||
:cursor (when (or hover? selected?)
|
|
||||||
(if (= (:resize-axis rect-data) :x) (cur/resize-ew 0) (cur/resize-ew 90)))
|
|
||||||
:opacity (if selected? 0.5 0.25)}}]))
|
:opacity (if selected? 0.5 0.25)}}]))
|
||||||
|
|
||||||
(mf/defc padding-rects [{:keys [frame zoom alt? shift?]}]
|
(mf/defc padding-rects [{:keys [frame zoom alt? shift?]}]
|
||||||
|
@ -661,9 +661,9 @@
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
|
:class (when (or hover? selected?)
|
||||||
|
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||||
:style {:fill (if (or hover? selected?) distance-color "none")
|
:style {:fill (if (or hover? selected?) distance-color "none")
|
||||||
:cursor (when (or hover? selected?)
|
|
||||||
(if (= (:resize-axis rect-data) :x) (cur/resize-ew 0) (cur/resize-ew 90)))
|
|
||||||
:opacity (if selected? 0.5 0.25)}}]))
|
:opacity (if selected? 0.5 0.25)}}]))
|
||||||
|
|
||||||
(mf/defc gap-rects [{:keys [frame zoom]}]
|
(mf/defc gap-rects [{:keys [frame zoom]}]
|
||||||
|
|
|
@ -99,10 +99,9 @@
|
||||||
:on-pointer-enter on-enter
|
:on-pointer-enter on-enter
|
||||||
:on-pointer-leave on-leave
|
:on-pointer-leave on-leave
|
||||||
:pointer-events (when-not preview? "visible")
|
:pointer-events (when-not preview? "visible")
|
||||||
:style {:cursor (cond
|
:class (cond (= edit-mode :draw) (cur/get-static "pen-node")
|
||||||
(= edit-mode :draw) cur/pen-node
|
(= edit-mode :move) (cur/get-static "pointer-node"))
|
||||||
(= edit-mode :move) cur/pointer-node)
|
:style {:stroke-width 0
|
||||||
:stroke-width 0
|
|
||||||
:fill "none"}}]]))
|
:fill "none"}}]]))
|
||||||
|
|
||||||
(mf/defc path-handler [{:keys [index prefix point handler zoom selected? hover? edit-mode snap-angle?]}]
|
(mf/defc path-handler [{:keys [index prefix point handler zoom selected? hover? edit-mode snap-angle?]}]
|
||||||
|
@ -160,8 +159,8 @@
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:on-pointer-enter on-enter
|
:on-pointer-enter on-enter
|
||||||
:on-pointer-leave on-leave
|
:on-pointer-leave on-leave
|
||||||
:style {:cursor (when (= edit-mode :move) cur/pointer-move)
|
:class (when (= edit-mode :move) (cur/get-static "pointer-move"))
|
||||||
:fill "none"
|
:style {:fill "none"
|
||||||
:stroke-width 0}}]])))
|
:stroke-width 0}}]])))
|
||||||
|
|
||||||
(mf/defc path-preview [{:keys [zoom command from]}]
|
(mf/defc path-preview [{:keys [zoom command from]}]
|
||||||
|
|
|
@ -222,8 +222,7 @@
|
||||||
|
|
||||||
[:div.text-editor
|
[:div.text-editor
|
||||||
{:ref self-ref
|
{:ref self-ref
|
||||||
:style {:cursor (cur/text (:rotation shape))
|
:style {:width (:width shape)
|
||||||
:width (:width shape)
|
|
||||||
:height (:height shape)
|
:height (:height shape)
|
||||||
;; We hide the editor when is blurred because otherwise the selection won't let us see
|
;; We hide the editor when is blurred because otherwise the selection won't let us see
|
||||||
;; the underlying text. Use opacity because display or visibility won't allow to recover
|
;; the underlying text. Use opacity because display or visibility won't allow to recover
|
||||||
|
@ -231,6 +230,7 @@
|
||||||
:opacity (when @blurred 0)}
|
:opacity (when @blurred 0)}
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:class (dom/classnames
|
:class (dom/classnames
|
||||||
|
(cur/get-dynamic "text" (:rotation shape)) true
|
||||||
:align-top (= (:vertical-align content "top") "top")
|
:align-top (= (:vertical-align content "top") "top")
|
||||||
:align-center (= (:vertical-align content) "center")
|
:align-center (= (:vertical-align content) "center")
|
||||||
:align-bottom (= (:vertical-align content) "bottom"))}
|
:align-bottom (= (:vertical-align content) "bottom"))}
|
||||||
|
|
|
@ -330,8 +330,8 @@
|
||||||
:key (str "viewport" page-id)
|
:key (str "viewport" page-id)
|
||||||
:view-box (utils/format-viewbox vbox)
|
:view-box (utils/format-viewbox vbox)
|
||||||
:ref on-viewport-ref
|
:ref on-viewport-ref
|
||||||
:class (when drawing-tool "drawing")
|
:class (dm/str @cursor (when drawing-tool "drawing"))
|
||||||
:style {:cursor @cursor :touch-action "none"}
|
:style {:touch-action "none"}
|
||||||
:fill "none"
|
:fill "none"
|
||||||
|
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
[app.main.data.workspace.grid-layout.editor :as dwge]
|
[app.main.data.workspace.grid-layout.editor :as dwge]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.cursors :as cur]
|
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
@ -230,15 +229,15 @@
|
||||||
[:rect.resize-handler
|
[:rect.resize-handler
|
||||||
{:x x
|
{:x x
|
||||||
:y y
|
:y y
|
||||||
|
:class (if (= type :column)
|
||||||
|
"resize-ew-0"
|
||||||
|
"resize-ns-0")
|
||||||
:height height
|
:height height
|
||||||
:width width
|
:width width
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
:style {:fill "transparent"
|
:style {:fill "transparent"}}]))
|
||||||
:cursor (if (= type :column)
|
|
||||||
(cur/resize-ew 0)
|
|
||||||
(cur/resize-ns 0))}}]))
|
|
||||||
|
|
||||||
(mf/defc editor
|
(mf/defc editor
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
|
|
@ -302,9 +302,9 @@
|
||||||
:y y
|
:y y
|
||||||
:width width
|
:width width
|
||||||
:height height
|
:height height
|
||||||
|
:class (if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0))
|
||||||
:style {:fill "none"
|
:style {:fill "none"
|
||||||
:pointer-events (if frame-guide-outside? "none" "fill")
|
:pointer-events (if frame-guide-outside? "none" "fill")}
|
||||||
:cursor (if (= axis :x) (cur/resize-ew 0) (cur/resize-ns 0))}
|
|
||||||
:on-pointer-enter on-pointer-enter
|
:on-pointer-enter on-pointer-enter
|
||||||
:on-pointer-leave on-pointer-leave
|
:on-pointer-leave on-pointer-leave
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
|
@ -417,9 +417,9 @@
|
||||||
:on-pointer-up on-pointer-up
|
:on-pointer-up on-pointer-up
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
|
:class (if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0))
|
||||||
:style {:fill "none"
|
:style {:fill "none"
|
||||||
:pointer-events "fill"
|
:pointer-events "fill"}}]))
|
||||||
:cursor (if (= axis :x) (cur/resize-ew 0) (cur/resize-ns 0))}}]))
|
|
||||||
|
|
||||||
(when (:new-position @state)
|
(when (:new-position @state)
|
||||||
[:& guide {:guide {:axis axis
|
[:& guide {:guide {:axis axis
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
[:div.pixel-overlay
|
[:div.pixel-overlay
|
||||||
{:id "pixel-overlay"
|
{:id "pixel-overlay"
|
||||||
:tab-index 0
|
:tab-index 0
|
||||||
:style {:cursor cur/picker}
|
:class (cur/get-static "picker")
|
||||||
:on-pointer-down handle-pointer-down-picker
|
:on-pointer-down handle-pointer-down-picker
|
||||||
:on-pointer-up handle-pointer-up-picker
|
:on-pointer-up handle-pointer-up-picker
|
||||||
:on-pointer-move handle-pointer-move-picker}
|
:on-pointer-move handle-pointer-move-picker}
|
||||||
|
|
|
@ -165,9 +165,9 @@
|
||||||
:top-right 90
|
:top-right 90
|
||||||
:bottom-right 180
|
:bottom-right 180
|
||||||
:bottom-left 270)]
|
:bottom-left 270)]
|
||||||
[:rect {:style {:cursor (cur/rotate (+ rotation angle))}
|
[:rect {:x x
|
||||||
:x x
|
|
||||||
:y y
|
:y y
|
||||||
|
:class (cur/get-dynamic "rotate" (+ rotation angle))
|
||||||
:width size
|
:width size
|
||||||
:height size
|
:height size
|
||||||
:fill (if (debug? :handlers) "blue" "none")
|
:fill (if (debug? :handlers) "blue" "none")
|
||||||
|
@ -180,8 +180,8 @@
|
||||||
(let [layout (mf/deref refs/workspace-layout)
|
(let [layout (mf/deref refs/workspace-layout)
|
||||||
scale-text (:scale-text layout)
|
scale-text (:scale-text layout)
|
||||||
cursor (if (#{:top-left :bottom-right} position)
|
cursor (if (#{:top-left :bottom-right} position)
|
||||||
(if scale-text (cur/scale-nesw rotation) (cur/resize-nesw rotation))
|
(if scale-text (cur/get-dynamic "scale-nesw" rotation) (cur/get-dynamic "resize-nesw" rotation))
|
||||||
(if scale-text (cur/scale-nwse rotation) (cur/resize-nwse rotation)))
|
(if scale-text (cur/get-dynamic "scale-nwse" rotation) (cur/get-dynamic "resize-nwse" rotation)))
|
||||||
{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)]
|
{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)]
|
||||||
|
|
||||||
[:g.resize-handler
|
[:g.resize-handler
|
||||||
|
@ -203,21 +203,21 @@
|
||||||
{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)]
|
{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)]
|
||||||
[:rect {:x cx'
|
[:rect {:x cx'
|
||||||
:y cy'
|
:y cy'
|
||||||
|
:class cursor
|
||||||
:width resize-point-circle-radius
|
:width resize-point-circle-radius
|
||||||
:height resize-point-circle-radius
|
:height resize-point-circle-radius
|
||||||
:transform (when rotation (dm/fmt "rotate(%, %, %)" rotation cx' cy'))
|
:transform (when rotation (dm/fmt "rotate(%, %, %)" rotation cx' cy'))
|
||||||
:style {:fill (if (debug? :handlers) "red" "none")
|
:style {:fill (if (debug? :handlers) "red" "none")
|
||||||
:stroke-width 0
|
:stroke-width 0}
|
||||||
:cursor cursor}
|
|
||||||
:on-pointer-down #(on-resize {:x cx' :y cy'} %)}])
|
:on-pointer-down #(on-resize {:x cx' :y cy'} %)}])
|
||||||
|
|
||||||
[:circle {:on-pointer-down #(on-resize {:x cx' :y cy'} %)
|
[:circle {:on-pointer-down #(on-resize {:x cx' :y cy'} %)
|
||||||
:r (/ resize-point-circle-radius zoom)
|
:r (/ resize-point-circle-radius zoom)
|
||||||
:cx cx'
|
:cx cx'
|
||||||
:cy cy'
|
:cy cy'
|
||||||
|
:class cursor
|
||||||
:style {:fill (if (debug? :handlers) "red" "none")
|
:style {:fill (if (debug? :handlers) "red" "none")
|
||||||
:stroke-width 0
|
:stroke-width 0}}])]))
|
||||||
:cursor cursor}}])]))
|
|
||||||
|
|
||||||
(mf/defc resize-side-handler
|
(mf/defc resize-side-handler
|
||||||
"The side handler is always rendered horizontally and then rotated"
|
"The side handler is always rendered horizontally and then rotated"
|
||||||
|
@ -246,13 +246,13 @@
|
||||||
:y target-y
|
:y target-y
|
||||||
:width length
|
:width length
|
||||||
:height height
|
:height height
|
||||||
|
:class (if (#{:left :right} position)
|
||||||
|
(if scale-text (cur/get-dynamic "scale-ew" rotation) (cur/get-dynamic "resize-ew" rotation))
|
||||||
|
(if scale-text (cur/get-dynamic "scale-ns" rotation) (cur/get-dynamic "resize-ns" rotation)))
|
||||||
:transform transform-str
|
:transform transform-str
|
||||||
:on-pointer-down #(on-resize res-point %)
|
:on-pointer-down #(on-resize res-point %)
|
||||||
:style {:fill (if (debug? :handlers) "yellow" "none")
|
:style {:fill (if (debug? :handlers) "yellow" "none")
|
||||||
:stroke-width 0
|
:stroke-width 0}}]]))
|
||||||
:cursor (if (#{:left :right} position)
|
|
||||||
(if scale-text (cur/scale-ew rotation) (cur/resize-ew rotation))
|
|
||||||
(if scale-text (cur/scale-ns rotation) (cur/resize-ns rotation))) }}]]))
|
|
||||||
|
|
||||||
(defn minimum-selrect [{:keys [x y width height] :as selrect}]
|
(defn minimum-selrect [{:keys [x y width height] :as selrect}]
|
||||||
(let [final-width (max width min-selrect-side)
|
(let [final-width (max width min-selrect-side)
|
||||||
|
|
|
@ -20,19 +20,19 @@
|
||||||
|
|
||||||
(defn get-cursor [cursor]
|
(defn get-cursor [cursor]
|
||||||
(case cursor
|
(case cursor
|
||||||
:hand cur/hand
|
:hand (cur/get-static "hand")
|
||||||
:comments cur/comments
|
:comments (cur/get-static "comments")
|
||||||
:create-artboard cur/create-artboard
|
:create-artboard (cur/get-static "create-artboard")
|
||||||
:create-rectangle cur/create-rectangle
|
:create-rectangle (cur/get-static "create-rectangle")
|
||||||
:create-ellipse cur/create-ellipse
|
:create-ellipse (cur/get-static "create-ellipse")
|
||||||
:pen cur/pen
|
:pen (cur/get-static "pen")
|
||||||
:pencil cur/pencil
|
:pencil (cur/get-static "pencil")
|
||||||
:create-shape cur/create-shape
|
:create-shape (cur/get-static "create-shape")
|
||||||
:duplicate cur/duplicate
|
:duplicate (cur/get-static "duplicate")
|
||||||
:zoom cur/zoom
|
:zoom (cur/get-static "zoom")
|
||||||
:zoom-in cur/zoom-in
|
:zoom-in (cur/get-static "zoom-in")
|
||||||
:zoom-out cur/zoom-out
|
:zoom-out (cur/get-static "zoom-out")
|
||||||
cur/pointer-inner))
|
(cur/get-static "pointer-inner")))
|
||||||
|
|
||||||
;; Ensure that the label has always the same font
|
;; Ensure that the label has always the same font
|
||||||
;; size, regardless of zoom
|
;; size, regardless of zoom
|
||||||
|
|
27
frontend/src/app/util/css.cljs
Normal file
27
frontend/src/app/util/css.cljs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
(ns app.util.css
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.util.dom :as dom]))
|
||||||
|
|
||||||
|
(defn declarations->str
|
||||||
|
"Converts an object of CSS declarations to a string"
|
||||||
|
[declarations]
|
||||||
|
(let [entries (.from js/Array (.entries js/Object declarations))]
|
||||||
|
(.reduce entries (fn [acc [k v]]
|
||||||
|
(dm/str acc k ": " v ";")) "")))
|
||||||
|
|
||||||
|
(defn add-rule
|
||||||
|
"Adds a CSS rule to a CSS Style Sheet"
|
||||||
|
[styleSheet selector declarations]
|
||||||
|
(.insertRule styleSheet (dm/str selector " {" (declarations->str declarations) "}")))
|
||||||
|
|
||||||
|
;; FIXME: Maybe we should rename this to `create-dynamic-style`?
|
||||||
|
(defn create-style
|
||||||
|
"Creates a new CSS Style Sheet and returns an object that allows adding rules to it"
|
||||||
|
[]
|
||||||
|
(let [style (dom/create-element "style")]
|
||||||
|
(dom/set-attribute! style "type" "text/css")
|
||||||
|
(dom/append-child! js/document.head style)
|
||||||
|
(js-obj "add" (partial add-rule (.-sheet style)))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue