Modify a tag body with a JS command

I’d like to toggle a <a>Read more</a> link to a <a>Read less</a> link.
Is it possible to update the tag content with a JS command?

As far as I know no, not with a JS command alone. You’ll have to go through the dispatch event dance and add a bit of JS:

Heex template:

  <a id="my-link">Read More</a>

  <button phx-click={JS.dispatch("js:read-less", detail: %{id: "my-link"})}>Click me</button>

Javascript:

window.addEventListener('js:read-less', event => {
    const el = document.getElementById(event.detail.id)
    el.innerText = "Read Less"
})
2 Likes

You could put in multiple links, which show/hide each other.

1 Like

That’s what I’m doing, thanks!
Just wanted to know if I was missing something obvious

Boom, from Elixir Forum to production, in minutes :wink:

https://phx-live-storybook-sample.fly.dev/storybook/components/block_and_slots/table?theme=default

2 Likes

I have to say, this storybook app looks really good. Congrats!

Maybe I naive question, but when I’m here:

https://phx-live-storybook-sample.fly.dev/storybook/components/buttons/button?tab=playground&theme=default&variation_id=custom_colors

And I click on “Code”, shouldn’t I be able to also edit the values of the bg-color and hover-bg-color attributes and try out different styles?

1 Like

Thank you!

Yes you should, but if you look at the component source, you can see that no attributes have been declared for bg-color and hover-bg-color. The component playground is feeding itself from component attributes introduced in LV 0.18 : no attr, no playground :slight_smile:

Thanks, that makes sense.

And if I were to declare an attribute for bg-color, would I be able to assign arbitary tailwind classes to it and see them applied live in the preview?

I’m asking because as you know tailwind only enables the classes that it finds in some specific files, so I wonder how LiveStorybook deals with tailwind classes that can be entered dynamically via its UI.

Misread :blush:

It those classes have not been safe-listed in Taiwind config it wouldn’t work.
But you can put a few class under your attr :examples key, that would make TailwindCSS bundle them.

1 Like

Yeah that’s not an easy problem to solve is it? Ideally you’d like to be able to play around with any new class without having to add stuff into the config or the examples.

I was able to solve the problem in one of my projects by having a process that writes all the dynamic class names to a file. However that only works for local dev where tailwind runs in watch mode. But it was only intended for testing stuff locally, so it’s fine.

So basically that’s why I was curious :slight_smile:

1 Like

That’s indeed easy to solve, but I am not even sure I want to solve it :wink:

Most of my components (such as this one) support style or colors properties as atom. They can also get their CSS extended, but it’s a bonus to adjust some margin / padding stuff

1 Like

Fair enough. If you restrict the options that can be customizable then it’s ok. However, I always thought that one nice feature of such a storybook app would be to quickly experiment with all sorts of fancy styles until you find the ones you like. That gets of course very limited if you can’t use the full power of your CSS framework.

Easy to solve? I was actually implying that it’s hard to solve. I could only come up with the hack I explained above, which only works locally. How would you solve it?

1 Like

sorry for the typo, I meant: “not easy to solve” :wink:

I think you can use the storybook this way if you safelist a whole bunch of styles.
For instance, I safe-listed all padding, margin with & height classes using regex:

// in tailwind.config.js
safelist: [
  { pattern: /^(w|h|m|p)-.+/ },
]
2 Likes

Tbh that’s imo a problem of tailwind. It was a decision on their end that classes are to be statically known in advance of building the css or to be safe-listed. Depending on how phx_live_storybook runs your application it could however be sneaky and write all its dynamic content to some file, where tailwind can pick it up. That will need reloading of the css as well though.

1 Like

Ah! I suspected it was a typo :smile:

Yeah that’s exactly the solution I outlined above, which I’m using for my project. It works well, but only in dev mode with auto-reload enabled (which is ok for my needs).

Nice! Didn’t think about that one

1 Like