dhleong / spade Goto Github PK
View Code? Open in Web Editor NEWA nice tool to use in the Garden
A nice tool to use in the Garden
Please support injection of <style>
tags into custom DOM targets, not just (.-head js/document)
which is hard-coded in inject!
.
There are at least two use cases for this:
For example, re-frame-10x is rendered into a shadow root then sets a *dom*
atom in a slightly modified spade so that <style>
tags are rendered inside the shadow dom.
It is not clear to me if the general solution in spade should be also global; i.e. two options would be
defclass
/ defglobal
render to some custom dom set early, or default to (.-head js/document)
if not setdefclass
/ defglobal
arg or meta so styles can be rendered to different dom contexts on a case by case basis if needed, or default to (.-head js/document)
if not setIn most cases, for any given input a style function should always return the same style. It turns out that we do not take advantage of that just now, but we could! Currently, whenever a style function is called, we:
This is great for local dev, since the factory code might have changed since the last time we ran it, but in production for most cases, 1, 2, and 5 are completely unnecessary, and 3 probably ought to be memoized.
I propose for v1.2.0 we do some refactoring. The new flow would look like:
<style>
element:always-compile-css?
compiler flag is true
(we will default to goog.DEBUG
so this does not happen in prod by default) we call the "factory" function to generate CSS as above and, if changed, update the DOMThis should significantly reduce overhead for the hot path case of using a style function in a virtualized list—and, well, just in general—while not requiring any changes to user code for most cases, or having any impact on the dev cycle.
For weird cases where a style should always be rebuilt each time it's used we could add an escape hatch by annotating the style function with metadata:
(defattrs ^:always-compile-css not-referentially-transparent-attrs []
{:color (js/Math.random) ; or whatever
...
})
I honestly can't think of a good use case for this, however, so this escape hatch might be deferred until someone asks for it (unless it turns out to be very simple to add).
I think we could very easily support this by supporting a special keyword :composes
in the root style. Here you just pass a class name, or a vector of class names, presumably from calling a defclass
style (eg: (style-class)
), or by doing a (:class (style-attrs))
thing, if you really want to. So it might look like this:
(defclass ship []
{:background "#999"}
[:.wings {:background "#777"}])
(defattrs stealth-ship []
{:composes (ship)
:background "#777"})
Seems very intuitive to me.
I'm not sure if I'm doing something wrong or if there's a bug with the media query implementation.
Here's what I tried:
(defclass test-class []
(at-media {:min-width "200px"}
{:margin-left "10em"})
{:background-color "blue"
:margin-left "1em"
:width "4em"
:height "4em"})
(defcard
test
"Testing media queries"
(fn []
(sab/html
[:div {:class (test-class)}])))
Here's what it results in:
The classes work perfectly except for media queries. I've tried all manner of things to get media queries to work, but nothing seems to take effect.
Please advise, thanks!
Is it possible to compose multiple styles ? E.g.
(defclass example
[]
{:composes [(shadow) (color-3) (big-text)]})
> (macroexpand '(defglobal x []))
(do
(clojure.core/defn
x-factory$
[style-name24459 params24460]
{:name style-name24459, :css (spade.runtime/compile-css [[]])})
(clojure.core/let
[factory-name24461 (spade.util/factory->name x-factory$)]
(def x
(spade.runtime/ensure-style! :global factory-name24461 x-factory$ nil))))
It should be clojure.core/def x
not just def x
. (And I'm not sure about cljs.core/do
vs. do
. I can't think clearly anymore, it's 4:30 a.m.)
Binding forms such as let
are incompatible with defclass
as such forms only return the value of the last form.
E.g.
(defclass example
[]
(let [a true]
{:background (if a :blue :grey)}
[:h4
{:color (if a :black :white)}]
[:&:hover
{:border [[(px 1) :solid :grey]]}]))
;; will only output
;; [:&:hover
;; {:border [[(px 1) :solid :grey]]
;; as the first 2 forms are ignored due to the let
The root cause of this is defclass
macro return semantics being different to defn
/ do
in that it returns all top level forms, instead of the value of the last form. Its understandable once analyzed that the above let
example does what it does in that context, but it is initially surprising behavior for a Clojure(Script) programmer. It certainly caught me out because I was trying to bind a common value with let
and it took me awhile to realise why all the styles were not coming through.
I'm not sure how to fix this. Maybe a mitigation such as allowing a single form return style for defclass
could work ? E.g.
(defclass example
[]
[(let ... ])
Global styling via defglobal
seems to not work with :simple
optimization. The weird thing is that global styles work just fine in :advanced
optimization.
Here's a lightweight, sample project for your viewing convenience:
https://github.com/sansarip/yacwat-simple
You can change the :optimization
level in the prod.cljs.edn
file to :simple
and then compile a jar that you can run with lein prod
- more detailed instructions in the README.
Is this intentional / am I doing something wrong?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.