When proposing or suggesting something please consider:
As my experience implementing getBoundingClientRect as Phoenix.LiveView.JS function and returns all the parameters of this JS function I mean (height, top, left and etc size) can be help full for complex client side component.
It keeps the ecosystem more clear and integrated. It can prevent the use of other client frameworks or js hook.
For example we have an accordion that is created with Phoenix component and Phoenix.LiveView.JS:
Show or open the accordion:
def show_accordion_content(js \\ %JS{}, id) when is_binary(id) do
js
|> JS.show(to: "##{id}")
|> JS.show(
to: "##{id}-content",
time: 500,
transition:
{
"transition-all transform ease-out duration-300",
"will-change-[opacity] opacity-0 h-0",
"will-change-auto opacity-100 h-[400px]"
}
)
end
As you see I use hard coded height h-[400px] because browsers do not accept transition for h-auto, we have all the commands to open an accordion in Phoenix liveView as you see except some information about the element. It forces me to use hook or something like AlpineJS.
It can be an option for JS.show, JS.hide and (before or after doing operation) etc.
They actually do but it’s experimental technology and the how is subject to change. Here’s another tutorial. It’s worth pointing out that this has been possible for years already with CSS grid but it’s kinda hacky because you have to wrap the component in a grid.
I think adding a function for Phoenix.LiveView.JS to return getBoundingClientRect parameters can be very useful because this is going to be very cheap and has a good Browser compatibility. even it is used many times in Phoenix LiveView js source and fix all the problems.
An update for css will not come soon, and if it does, it will take a long time to be supported in all browsers
FWIW I agree with you. I’ve been thinking for a while Phoenix could provide a sort of standard library for common JS functions. Another big one is updating whatever structure is tracking changes on the front end. Perhaps declaring default values and types like attrs in components but they can be manipulated by JS functions client side (with all the code written in LiveView/Elixir/Plug style). A use case for this is optimistic renders on form submissions.
My point with the comment above is more so for people interested in CSS that have yet to be exposed to modern capabilities
Based on my experience, if such things are not done especially (what you said) in the client side. People’s interest in bringing JS ecosystem frameworks is increasing.
And this is exactly the point where I have to say that like js, everyone creating something rather than solving the previous problem. I hope it doesn’t happen like this
I’m imagining something like Alpine but instead of updating the DOM directly it updates dynamic assigns on LiveViews existing change tracker, and then LiveView updates the DOM like normal.
I do not want to send from server to client, I need some tools client to client even have a global state for client or access to service worker client to client etc
The JS commands are pre-computed and transformed into a JSON format (you can literally see it in the DOM). There is no mechanism to send information from the client back to the server to re-compute the JS command with the bounding rect, and doing so would represent a substantial increase in both complexity and latency (two round trips to render).
You could instead redesign JS commands to support some sort of variable system, which would again be a substantial increase in complexity and in the limit would inevitably converge on a turing complete system (i.e. JS commands would become an ad-hoc programming language), which sounds to me like a very bad idea. We already have a programming language for the client (JavaScript).
I think a much better path forward would be to continue to improve hooks for use cases like these. In particular, I don’t understand why there’s no good API for setting sticky attributes/classes the way JS commands do via the client-side hooks APIs. There is a somewhat-hacky way to do it (which I have used, and it works) by executing a pre-computed JS command stored in an attribute but I think we could do a lot better than that
P.S. You should just use the grid trick for this, I’ve used it extensively and it works just fine with JS.toggle_class. You don’t even need the JS transition for this, you can just use CSS (the element never leaves the DOM).
I did not elaborate because the grid trick in question was linked above Here is a StackOverflow question with more details:
Honestly you probably could find a way to do it with radio buttons and pure CSS, but I wouldn’t. What I meant was that the animation can all be done with CSS (no JS.transition needed), and then all you need is JS.toggle_class to trigger the CSS animations.
First, you wrap each item in a grid container, and then you use CSS to toggle grid-template-rows between 0fr and 1fr. You set overflow: hidden on the child (the accordion content in your case) so that it’s not visible when closed.
Yes, In the last month I was wondering the same (and was thinking about creating a proposal to add that). I created a local fork of live view locally where I exposed the sticky API in the socket to try it out and that made my hooks way easier to implement and reason about.
For me it seems like a win-win situation, but maybe there is some corner case that I’m not aware that would justify not exposing it. Maybe some dev from the LiveView team could bring more light to this.
I love LiveView, but I have to admit that, in my experience, it is a pain and hard to get it right when you need to create some more “complex” components with the current hook solution.
The code I’ve written to get around this issue (using the liveSocket to trigger JS commands in data- attributes) is some of my least favorite in my app - it’s obviously suboptimal. I think opening up the sticky API is inevitable, and I don’t see any obvious problems (it’s the same thing we’re already doing anyway, just directly). I would imagine the work simply hasn’t been done yet - JS commands are still relatively new and improving quickly. We only just got toggle_class, which was a big improvement
which API do you refer to? getBoundingClientRect? If that’s the case then no, we don’t work on it and we also wouldn’t want to expose this through Phoenix.LiveView.JS.