This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-04
Channels
- # announcements (9)
- # bangalore-clj (1)
- # beginners (164)
- # calva (7)
- # clj-kondo (12)
- # cljs-dev (5)
- # cljsrn (7)
- # clojure (100)
- # clojure-spec (5)
- # clojure-sweden (2)
- # clojure-uk (4)
- # clojurescript (9)
- # conjure (22)
- # datomic (53)
- # fulcro (62)
- # graalvm (27)
- # helix (10)
- # joker (6)
- # malli (1)
- # mount (4)
- # nrepl (3)
- # off-topic (8)
- # quil (1)
- # releases (1)
- # sci (42)
- # shadow-cljs (1)
- # testing (7)
- # tools-deps (26)
- # vim (24)
Has someone here worked with fulcro-garden-css? I am not really sure how to use it... The readme is a bit confusing
Yes. Though something was missing in my setup because I had to add :css-include [Header Content]
into my Root to get the styles from children working, which should not be needed thanks to the "autoinclude". The defsc Header
then has this among its options (here i am using global styles for simplicity):
:css-global [[:.main-header {:display 'block
:padding-top "3rem"
:padding-bottom "1.2rem"
:background-color "#FFF"
:margin 0
:text-align 'center}
[:&__logo {:margin "0 auto 5rem auto"
:height "3rem"
:padding "0"}
[:& :svg {:width "auto"
:height "3rem"}]]
[:&__text {:margin "0 auto 3rem auto"}]
[:&__step-indicator {:margin "0 auto 0 auto"}
[:&--hidden {:display "none"}]]]]
So it is essentially LESS-like styling on the component. In my client.cljs
in refresh/init I have
(com.fulcrologic.fulcro-css.css-injection/upsert-css "componentcss" {:component root/Root})
The auto-include feature uses the query to find things. If you have css in things that are not part of your (static startup) query, then it cannot work, and you must construct the tree manually with the includes.
@U2APCNHCN don't hesitate to send a PR to improve the docs 🙏 :)
Oh I am working on that :) And if my auth stuff from the other day works out, I'll check back with you guys if that's either something for RAD even, or if I just release it as a lib for RAD.
Oh, I didn't even know about :css-global
. Do the ones defined there propagate down to the children?
The create global styles (so class main-header
etc), not prefix with the component name so that yes, they apply to any component on the page that uses the given css class name.
No, it does the same thing as LESS so here (notice the nesting) &__logo
becomes .main-header__logo
- http://lesscss.org/features/#parent-selectors-feature
And if I interpret the source code of css_injection.cljc correctly, that "componentcss" is the id of the top-level element in your DOM?
I do not think so. I think it generates a <style ...>
and perhaps uses the id there somehow. I don't have the app running so cannot check.
Prefer the docstrings…look through them all. It’s really not much code. https://github.com/fulcrologic/fulcro-garden-css/blob/develop/src/main/com/fulcrologic/fulcro_css/css_injection.cljc
Okay, there's this one thing I don't get yet. When I use a defsc component A inside a defsc component B, how can I have defsc A load data from the database and have it available in its props? And if that isn't possible, how do I idiomatically access the data in the normalized database without having it in the defsc query?
don’t think of “components loading data”. Components are UI. They display things. You logic should be triggered by specific things in your system, like initialization on startup, and user-driven (or time-based) events that trigger mutations/loads.
something is always happening when you want a load: either you just started the app, or somebody interacted.
If the interaction was a “route”, then the logic that triggers (or accepts) the route is where the loading goes
Again, see RAD’s UISM implementations for forms or reports. Most everything there is either triggered off of a state machine handler due to a user interaction, or the result of a route.
Well in this case I want to load when the component gets initialized. I have it in :componentDidMount
currently. And it does load the data successfully into the database. But since the props are controlled by the parent...
“props controlled by the parent” is important why? And CDM is a bad place for loading.
Yes, but when, in a component B, I do (ui-component-a props) then ui-component-a (or rather ComponentA behind it) gets initialized?
that renders component A inside component B but it doesn't have anything to do with the loading of data
Okay, so :componentDidMount
is a bad place to call df/load!
. What place is better?
Yes, so basically, it is routing. The user goes to the page, and the data is supposed to load. But I don't want to clutter the parent with it.
or you could code a concept similar to that if you’re not using Fulcro’s dynamic router
i guess once reason why CDM is bad is that the component will be rendered but without data to hydrate it for a bit
is that the main reason or is there also a reason to be hesitant to co-locate loads with components?
well, and a component itself probably does not know it’s own identity, and CDM can be called for spurious other rendering concerns (i.e. a parent’s key changes)
coupling I/O with UI rendering is just a bad practice…subscriptions can be ok in CDM/CWU
So I guess when I use will-enter, that means I have to put all the loading for that route into the parent, right? Well I guess in some way that might be the sane approach anyway
I will sometimes put those in CDM, but not directly as loads. I’ll make some kind of cache for them, and CDM will have something like ensure-picker-options
but you still have to know what thing you’re linking them into, or you can just use link queries
CDM has this…`(app/current-state this)`. The cache for your dropdown options would be well-known and normalized.
so rummaging around in app/current-state is acceptable when you're trying to do things like determine whether a load should happen on a lifecycle/routing hook? i found myself wanting to do it yesterday but wondered if i was going to end up with a tight coupling somehow. in other frameworks i think i might have been right, but since fulcro's db is normalized i think the coupling shouldn't be as tight
you’re just looking at your database. The only mistake you can make there is to use data out of the db in your UI rendering without it being in the query. Such a use will fail to refresh properly, because shouldComponentUpdate will not see the change in props
so, the easy rule: if you render it: query for it. If it is for some other purpose (stateful decisions in lifecycle) then go for it.
same goes for swapping on the state atom. It’s your database. Fulcro will not re-render if you swap on the atom, but it’s just data.
The “formalisms” of Fulcro: mutations, loads, UI queries…those have two main purposes: 1. To establish norms that everyone understands that aim to keep your code and data consistent and understandable. 2. Provide a way for Fulcro to comprehend that something has changed that requires a UI refresh. It is right to be cautious about reaching outside of them, since lack of understanding can lead you to get unexpected results; however, the overall system is pretty simple. queries fill props, components get props, SCU short-circuits rendering if props have not changed, mutations trigger rendering refresh (which is a query followed by sending the props). Loads are “fancy mutations” put data in the database from a remote.
If you twiddle around with the state atom none of that “closed loop” knows about it. Simple as that.