Garden Generated Inline-стили в Reagent's Hiccup

В реагенте можно указать встроенные стили CSS следующим образом:

[:div {:style {:border "1px solid red"}} "My Text"]

garden может сделать такие свойства CSS, содержащие несколько значений в списке, более общими. Векторы для списков, разделенных запятыми, и вложенные векторы (используемые здесь) для списков, разделенных пробелами:

(require '[garden.core :refer [style]])

(style {:border [[:1px :solid :black]]})
;= "border: 1px solid red;"

Как эти вещи можно совместить? Реагент, кажется, упрямо принимает только хэш-карты для атрибута стиля. Принятие строки также было бы решением здесь.

Как правило, встроенные стили не являются хорошим выбором в долгосрочной перспективе. Таким образом, это можно решить, присоединив класс к div и указав его стиль глобально с помощью функции gardens css.

Пример класса:

[:div.myclass "My Text"]

(css [:.myclass {:border [[:1px :solid :black]]}])
;= ".myclass {\n  border: 1px solid black;\n}"

Однако иногда полезно начинать со встроенных стилей, поэтому: Есть ли способ сделать это так, как описано выше?


person Anton Harald    schedule 09.05.2016    source источник
comment
Лично я ввожу (goog.style/installStyles) и удаляю (goog.style/uninstallStyles) при перезагрузке фигового колеса. Прекрасно работает. Вы не можете указать некоторые встроенные атрибуты, поэтому вы столкнетесь с проблемами раньше или позже.   -  person ClojureMostly    schedule 09.05.2016


Ответы (3)


Хэш-карта, которая может быть дополнительно предоставлена ​​для векторов икоты реагента, в основном является абстракцией атрибутов HTML указанного элемента html. (Как они представлены в DOM) Кроме того, при присоединении к ключевому слову :style может быть вложена еще одна хэш-карта. Это абстракция свойств стиля элемента. Что отличается от того, что выше. По этой причине можно было бы утверждать, что эти две вещи лучше было бы держать отдельно, однако это было бы проще сделать по-другому.

Манипулирование свойствами стиля элемента путем установки его атрибута стиля будет означать, что вся строка стиля должна анализироваться при изменении только одной части. Таким образом, наличие дополнительной опции для предоставления строки стиля в икоте не сильно помогло бы.

Похоже, сад может отображать только строки. Я бы предположил, что было бы полезно, если бы он также отображал хэш-карту.

Однако есть обходной путь, который позволяет реагенту и саду работать вместе:

(defn css-map [s]
  (->> (style s)
       (re-seq #"(.*): (.*);(?:\n|$)")
       (reduce (fn [m [_ k v]]
                 (assoc m k v))
               {})))

(css-map {:border [[:1px :solid :red]]
          :background-color (rgb 33 5 0)})
;= {"border" "1px solid red", "background-color" "#210500"}

Производительность от этого, конечно, пострадает. Если кто-то знает лучшее решение, мне все равно было бы любопытно узнать.

person Anton Harald    schedule 09.05.2016

Взгляните на stylefy. Он позволяет прикреплять стили, определенные как данные, к компонентам реагентов: Например:

(def button-style {:padding "25px"
                   :background-color "#BBBBBB"
                   :border "1px solid black"})
(defn- button [text]
   [:div (use-style button-style)
      text])
person Victor Gil    schedule 30.12.2018
comment
Вопрос был задан о Garden, а не о stylefy. - person the_dude; 02.01.2020
comment
Я упомянул stylefy, потому что он использует Garden под капотом. - person Victor Gil; 17.02.2020

Я использую garden с goog.style/installSafeStyleSheet, как это было предложено ClojureMostly.

Я также играю с созданием css с ограниченной областью действия, в настоящее время с (random-uuid). Если я заставлю его работать хорошо, я обновлю этот ответ.

(ns stuff
  (:require
    [goog.dom :as gdom]
    [goog.style :as gstyle]
    [garden.core :refer [css]])
  (:import [goog.html SafeStyleSheet]
           [goog.string Const]))

(defn install-styles! []
 (gstyle/installSafeStyleSheet
  (SafeStyleSheet/fromConstant
   (Const/from
    (css [:.someclass {:color 'red}])))))

(def ref-to-installed-style (install-styles!))

(defn app []
 [:h1.someclass "Red Hello world!"])

;; Reagent and Figwheel stuff. On figwheel reload, call
;; (gstyle/uninstallStyles ref-to-installed-style), and then
;; install it again, to avoid duplication.

Примечание: здесь может быть ошибка, если компонент рендерится до установки стилей. Все еще не уверен, как это исправить.

person marcelocra    schedule 16.08.2020