Fork me on GitHub
Richard Bowen02:07:55

Hey. When pre-pending an icon to a button with Material UI the <Icon>icon-name</Icon> component is passed to the startIcon prop. How is the equivalent in ClojureScript?


{:start-icon (reagent/as-element [:> Icon "icon-name"])}

Richard Bowen01:07:10

Interesting. I'll give it a try. Thanks.

Richard Bowen00:07:07

Didn't get this working. I have tried a few things: • What you suggested • Importing an icon ["@material-ui/icons/Save" :as save-icon] and attempting to use it like so: [button {:start-icon save-icon}] and other variations of that. An error is returned when this is used. • Using [button {...} [icon "icon-name"]] (`icon` is just material-ui/core/Icon after reagent/adapt-react-class has been applied) Any ideas?


> An error is returned What error?


In your MUI imports, replace :as with :default.

max minoS05:07:05

I am trying to use garden in my reagent project and I cant get figwheel to reload it properly

(ns ^:figwheel-hooks proj.core
   [garden.core :refer [css]]
   [reagent.dom :as d])
   [goog.html SafeStyleSheet]
   [goog.string Const]))

(def style
  (css [:.something {:font-size "76px"}]))

(defn install-styles! []
    (Const/from style))))

(def stylesheet (install-styles!))

(defn ^:after-load re-render []
  (install-styles!)                         ;; (1)

(defn ^:before-load unmount []
  ( stylesheet)
  (d/unmount-component-at-node (.getElementById js/document "root")))
1. I feel like the second call to the install-styles! function is incorrect because it will lose the reference used to unmount it. Should I redefine it instead in the global scope (against immunitability)? This works but it returns `Use of undeclared Var goog.html.SafeStyleSheet/fromConstant` when I change the style and save.


1. Use defonce instead of def for anything that should persist between reloads 2. I think you can just (set! stylesheet (install-styles!)) later Also, pretty sure there's no need to call d/unmount-component-at-node - mount will do it anyway.

max minoS09:07:22

I tried changing it into defonce for the setup and using set! for the reloads, but it still doesnt work. Everytime I change the CSS it just gives the same error.


Seems like the error is completely unrelated to the above. What's the stacktrace of that error?

max minoS09:07:08

This is what I got from the console:

[Figwheel] Compile Warning - Use of undeclared Var goog.html.SafeStyleSheet/fromConstant in file src/reagent_portfolio/core.cljs at line 58, column 5 
overrideMethod	@	react_devtools_backend.js:2574
goog.debug.Console.logToConsole_	@	console.js:219
goog.debug.Console.addLogRecord	@	console.js:125
(anonymous)	@	log.js:205
publish	@	log.js:204
goog.log.log	@	log.js:338
goog.log.warning	@	log.js:348
figwheel$core$glog_warning	@	core.cljc:131
figwheel$core$compile_warnings	@	core.cljc:333
figwheel$core$compile_warnings_remote	@	core.cljc:336
eval	@	VM511:1
figwheel$repl$eval_javascript_STAR__STAR_	@	repl.cljc:353
(anonymous)	@	repl.cljc:383
G__13070__2	@	core.cljs:11198
G__13070	@	core.cljs:11184
(anonymous)	@	repl.cljc:476	@	eventtarget.js:351	@	eventtarget.js:481	@	eventtarget.js:201

max minoS09:07:37

Curiously, the SafeStyleSheet/fromConstant works on the first load, it only breaks on reloads


reagent-portfolio.core is the NS that has that example code above? And the line 58 is inside install-styles!?

max minoS09:07:57

Line 58 is (SafeStyleSheet/fromConstant


Very interesting. No clue what's going on but feels like somehow figwheel messes up imports upon reloading. What if you replace [goog.html SafeStyleSheet] import with [goog.html.SafeStyleSheet] require?


Also, try adding (js/console.log goog.html.SafeStyleSheet) as the first line of install-styles! and see what it outputs.

max minoS09:07:40

I've tried require-ing instead of importing these:

[goog.html.SafeStyleSheet :as SafeStyleSheet]
   [goog.string.Const :as Const]
There wasnt any difference

max minoS09:07:41

This is what I got from console logging the SafeStyleSheet. It only ran on startup.

class SafeStyleSheet {
  constructor(value, token) {     this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = token === CONSTRUCTOR_TOKEN_PRIVATE ? value : "";

max minoS09:07:13

Also I ran it first before anything else in the function, so even before the line with error.


If you expand that object in the JS console (might need to right click on it and press "Display as JS object" or something like that), do you still see the fromConstant member there?

max minoS09:07:08

I'm not sure if this is what you mean but I went into the Sources tab and searched fromConstant, this is the method within the safestylesheet.js:

static fromConstant(styleSheet) {
    const styleSheetString = Const.unwrap(styleSheet);
    if (styleSheetString.length === 0) {
      return SafeStyleSheet.EMPTY;
    assert(!contains(styleSheetString, "\x3c"), `Forbidden '<' character in style sheet string: ${styleSheetString}`);
    return SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString);


No, I mean whether you can see it being present a run-time, in the results of js/console.log


Two other things I'd try: • Split that namespace into two - one with all the code and the other with all the hooks that does nothing but call the functions from the former namespace • Create a small project that uses a different build tool and see if you can reproduce it there

max minoS09:07:40

It doesn't print it as a JS object, and when I right-click it it only asks whether I want to Store function as global variable or Show function definition

max minoS09:07:43

I tried to split the namespace, like you said, and it still returns the same error, it also still worked the same on first load


Absolutely no clue. If you can't reproduce it in a small project that uses e.g. shadow-cljs, I'd create an issue in Figwheel's bugtracker. Try also asking in #figwheel or #figwheel-main - depending on what you're using.

max minoS09:07:55

I will tinker it a little more and I'll make sure to do that, thanks a lot for helping!

👍 3
max minoS09:07:51

fyi, this is the stackoverflow answer that I followed:

Asko Nōmm06:07:21

Hi! I have a question regarding deployment to Clojars. Namely if I declare dependencies in the project.clj file, and then run lein deploy clojars as per usual - then are those dependencies already downloaded when a user downloads my Clojars package? Or do they need to also add those dependencies to project.clj?

Asko Nōmm06:07:27

I suppose what I’m asking is, how do I make it so that my Clojars package already includes the dependencies when a user downloads my package?


It must not include those dependencies. It should specify those dependencies in pom.xml. Check the resulting jar that lein deploy clojars generates - if there's pom.xml somewhere in META-INF there with all the right dependencies, then you should be all set. But also don't trust me on this one and just check on a test project because I've never done it myself and only read other people's discussions on it.


There are only four cases that I can think of when other people should specify [some of] the dependencies of your library in their own projects manually: • They simply depend on the same thing • They want to override your dependency with a different version • Your dependency is optional (not sure if it works in CLJS, but it's used somewhat regularly in CLJ) • Your dependency is not in Clojars but instead in NPM, so it will go into package.json

Asko Nōmm17:07:11

I checked the pom.xml and the dependencies are there you’re right! Thank you @U2FRKM4TW.

👍 3

Taking a poll. Background: I am starting on applying my #matrix dataflow hack to CLJS+RN. This will be the first reactive CLJS+RN that does not build on the estimable Reagent. (Wait. What are Hoplon/Javelin up to?) It will also steer clear of the Flux paradigm followed by re-frame. My starting point is Helix: I like minimal, and I do not like JSX or Hiccup. I like: (defnc app [] (let [[state set-state] (hooks/use-state {:name "Helix User"})] (d/div (d/h1 "Welcome!") ;; create elements out of components ($ greeting {:name (:name state)}) (d/input {:value (:name state) :on-change #(set-state assoc :name (.. % -target -value))})))) Related: Cool, I did not realize #fulcro went the same way. But even wild and crazy Clojurians are creatures of habit, so: Q: How important is Hiccup to your front-end tool selection? Thx! 🙏

Geoffrey Gaillard13:07:20

Not that important to me. Could it be added as sugar afterwards?


I have to think post hoc Hiccup would be straightforward to implement. Helix itself demonstrates the power of macros and a few lines of code to transform icky interop into its own preferred syntax. Likewise my MatrixRN will start as icky Helix/hooks abuse and get macro-fied into coding elegance. I, a heavy CL macro user, do not use macros any more in Clojure, but a library like this is the perfect use case.


I don’t use hiccup for building user interfaces, but I'm pretty far off the beaten path.


If you're interested in seeing what other libraries are doing in the design space, you may also be interested in @U05224H0W’s and

👍 4

I use pure interop as well; no hiccup, reagent, etc; one atom drives the whole state, more or less


@UCJCPTW8J Thx! I agree with @U05224H0W on CLJS doing well by ditching React. Me, I never even considered it: But now I want to take Matrix mobile, and RN seems like it might be the best way to get JS, hence CLS, and native performance. Right now I am trying to get Matrix+React for web working merely as a training exercise on elements vs components, and the useState hook. Helix is proving quite helpful in that it is about the only CLJS+React library not standing on the shoulders of Reagent.

👍 2