fulcro 2024-11-15

Has anyone considered/is using guardrails for defsc ?

eg I have this generic component:

(defsc DeleteModal
  "Common Delete modal
   - title :- string; Heading of delete modal, by default used `brian.ui.modal/destructive-action-title`
   - content-description :- string or dom/; Texting or block which will be shown at the top of modal conent
   - dependencies :- collection of strings; List of dependencies which user chould mark as checked to confirm the delete operation
   - dependencies-heading :- string or dom/; Texting or block which will be shown above `dependencies`. Default label `You are about to delete:`
   - validate-input-target :- string; String which user should type to confirm the delete operation
   - validate-input-header :- string or dom/; Texting or block which will be shown above `validate-input` section
   - delete-label :- string; Label for delete button inside of modal
   - on-delete :- (fn []); Function/callback on delete confimed
   - open-label :- string; Label of button which opens delete modal
   - on-open :- (fn []); Function/callback on open modal
   - open-className :- string; Class name for open modal button
   - open-disabled? :- boolen; If true open button will remain with opacity & wouldn't be clickable
   - on-close :- (fn []); Function/callback on modal close
   - loading? :- boolean; If true modal & open button will show loading indicators"
  [this {:keys [title content-description dependencies dependencies-heading
                validate-input-target validate-input-header delete-label on-delete
                open-label on-open open-className open-disabled? on-close loading?]}]

feels like quite a good candidate for having the arg list turned into a spec

When you make the factory, make it a >defn rather than a def

Hmm, almost got it:

(defsc LazyImage
  [this {:keys [src placeholder className alt]}]
  {:initial-state (fn [_] {:loaded? false})}
  (let [{:keys [loaded?]} (comp/get-state this)]
    (sui/ui-visibility
      {:onTopVisible #(comp/set-state! this {:loaded? true})}
      (sui/ui-image
        {:className (or className "ui image")
         :alt alt
         :src (if loaded? src placeholder)
         :data-src src}))))

(def ui-lazy-image (comp/factory LazyImage))
ro/column-formatters
   {:foo/name
    (fn [_this v {:foo/keys [image-filename
                             location]}]
      (dom/h4 :.ui.image.header
              (ui-lazy-image {:src (str "/images/" image-filename)
                              :placeholder "/images/placeholder.png"
                              :alt "A lazy loaded image"
                              :className "ui mini rounded image"})
              (div :.content v
                   (div :.sub.header location))))
but the problem here is the images that are in the top rows and visible when the page loads show the placeholder image until I start to scroll.

I’m not familiar with the approach you are trying. What I’ve done in the past is take control of the Row component (make my own row defsc) and use something like componentDidMount…that works as long as you make sure the row key is something truly unique (or pagination, which uses index numbers for the rows) won’t see the components as “remounting” on the next page, and will optimize away the side effect.

but if you’re trying to get it via “scroll visibility” you’ll have to play more js games

Yeah, I'm going for "scroll visibility" because in this report I have a fairly limited number of rows so I'm choosing not to paginate, but the images do take some time to load and loading the whole set of them before they're even visible adds to the load time. I added :fireOnMount true from the factory and it helps, but kinda in the opposite way 😄 the images at the top all start with the placeholder and don't switch to the actual image at any time, but the rest of it all works as intended. Tried to fiddle with the :offset param too, but that didn't move things in the right direction.

nice post, looking forward to reading more and hearing about your fulcro projects.

I posted an article on how I added lazy loading to an image column in my RAD report. Happy to accept suggestions/corrections! Here it is in case anyone finds this helpful in the future: https://fnguy.com/RAD_lazy_images.html