Fork me on GitHub
#reagent
<
2021-09-07
>
Ovidiu Stoica12:09:50

Hei guys, what is the fastest way to import svgs? Let's say an svg exported from figma. How do you convert it to hiccup style? I tried to manually “translate” from jsx to hiccup but it doesn't really work

p-himik13:09:41

> How do you convert it to hiccup style? Just don't. SVGs are not JSX, they're are valid HTML entities. You can embed them via e.g. "dangerously set HTML" (don't recall the exact name and usage of it in React).

tobias05:09:27

Another option is to parse the svg with the hickory library and then output to svg https://github.com/davidsantiago/hickory

yiorgos13:09:10

Hi all, Is it possible to use a static SVG file like a component in reagent for example in React you can do:

import React from 'react';
import {ReactComponent as ReactLogo} from './logo.svg';

const App = () => {
  return (
    <div className="App">
      <ReactLogo />
    </div>
  );
}

2
p-himik13:09:45

Not like that. But in a somewhat similar way. This page describes how it can be done with shadow-cljs, but you can easily adapt the solution to any other tool: https://clojureverse.org/t/using-none-code-resources-in-cljs-builds/3745

👍 2
yiorgos13:09:49

I guess you can’t pass props to it, like React.

p-himik13:09:19

Right, that you cannot do - for that you'd need to parse it as Hiccup at compile time, modify it (probably at run time), and then use as Hiccup.

👍 2
p-himik13:09:42

I have this code in one of my projects.

(ns my.proj.svg
  (:require [hickory.core :refer [parse-fragment as-hiccup]]
            [ :as io]))

(defn- update-viewbox-attr [attrs]
  (if-some [[_ vb] (find attrs :viewbox)]
    (-> attrs
        (assoc :view-box vb)
        (dissoc :viewbox))
    attrs))

(defmacro embed-svg [path attrs]
  (assert (string? path))
  (let [svg-vec (-> (io/resource path)
                    slurp
                    parse-fragment
                    first
                    as-hiccup
                    (update 1 update-viewbox-attr))]
    `(update ~svg-vec 1 merge ~attrs)))

p-himik13:09:54

@U01JA0VU7P0 ^ in case you need to change the attributes as well.

p-himik13:09:21

And then use it as just

[:div {:class :some-container-thats-just-for-demonstration-but-is-not-needed}
  (embed-svg "resources/item.svg" {:class-name :item
                                   :width      150})]

yiorgos13:09:09

Sweet, thank you very much!

👍 2
alexdavis14:09:30

you could make a jsx/tsx file that exports your svg component and import it into your clojurescript project and use it with adapt-react-class (`:>`) like

-- foo.jsx --
export const Foo = () => {
  return (
    <div className="App">
      <svg>
..........
      </svg>
    </div>
  );
}

-- foo.cljs --
(require '["js/foo" :refer [Foo]]) 
(defn view
 []
  [:> Foo {:some-props ...
you need to use babel or something to convert the jsx/tsx and write it to js/foo.js (in my example), or if you don’t want to do that you can just write a plain js file yourself and import it straight away, but you’d need to do the React.createElement stuff and not use jsx

alexdavis14:09:11

This technique is much more useful if you already have jsx files you want to use though, if you just want to use an svg its probably not the best solution

👍 2
Fredrik Andersson20:09:08

whats the best practice to capture a form submit in reagent?

p-himik20:09:26

Same as in vanilla JavaScript - just handle the event and cancel it.