Open nmzein opened 2 weeks ago
That issue doesnt seem to mention boundingClientRect. I know that svelte already has bindings for contentRect among other things but these do not provide the same functionality. Unless I'm mistaken
Can you explain what exactly the difference is for your use-case?
Im not aware of any of the existing bindings giving absolute x, y positions of the bounded to div. ContentRect just gives the dimensions of the div without taking into account its position at all. Binding to boundingClientRect would also allow you to get the clientWidth and clientHeight at the same time as the absolute x and y pos without making extra bindings for those separately. This is another area where contentRect differs from boundingClientRect where contentRect doesnt include the padding in the width and height of the object which forces you to either calculate it or use clientWidth and clientHeight bindings.
This sounds like something you can solve through an action.
Which is what I did eventually. Thought it would be nicer to have this built-in though since it can be confusing as to why it doesn't exist. If theres no drawbacks to having this included is there a reason not to?
If theres no drawbacks
Don't you need to poll this? How did you implement it? Maybe having this as a binding is a footgun when you should only call getBoundingClientRect
when you need to.
Don't you need to poll this?
Not necessarily, the existing bindings use a ResizeObserver
if possible.
Not necessarily, the existing bindings use a
ResizeObserver
if possible.
getBoundingClientRect
depends on the scroll position (among others), so you'd need to poll it or imperatively call it when you need it (I wouldn't poll it with raf). You can't solely rely on ResizeObserver
. That's what I meant with "having this as a binding is a footgun". It needs to be used carefully depending on the requirements.
Yes you do have to poll because ResizeObserver
would only run when the div was resized not when it was dragged and moved. I personally think even if its a "footgun" it should be available since if people really need it they will create it themselves anyways. Polling does not create that bad of a performance penalty unless used in excess. IMO this is where documentation steps in to tell people to use things carefully.
The size bindings also used polling as a fallback (but will switch to ResizeObserver
permanently in v5).
The polling was only initiated if a binding existed, so it's not degrading general performance.
Yeah but boundingClientRect doesnt only give you size information but positional. I dont believe a ResizeObserver would be able to detect changes to position no? Please correct me if I'm wrong.
Yes, I was just pointing out the precedent for polling and its implications. As @Prinzhorn already noted, an observer would not be enough here, unfortunately.
Right. So what I'm getting is you wouldnt be against adding this even though its implemented using polling right? If thats the case I could maybe try to navigate myself through the source code and start figuring out what needs to be added.
I'm not a maintainer, @dummdidumm is, and he suggested to use an action. With Svelte 5 coming up, I'm inclined to agree.
In earlier versions, the ergonomics of having an action that updates a value were not great. Usually you would have to do things like using a separate store or maybe pass a setter function around.
With runes you can create a utility that hosts an action and the value. So the end user code really does not change all that much, e.g.
<script>
+ import { createClientRectTracker } from './client-rect-tracker.svelte.js';
- let clientRect = $state(null);
+ const clientRectTracker = createClientRectTracker();
</script>
- X: {clientRect?.x} <br>
- Y: {clientRect?.y} <br>
+ X: {clientRectTracker.value?.x} <br>
+ Y: {clientRectTracker.value?.y} <br>
- <div bind:boundingClientRect={clientRect}> ... </div>
+ <div use:clientRectTracker.action> ... </div>
Example action (Try this in Firefox. Chromium throttles the polling due to some broken out-of-focus detection or something like that.)
With a separate action you also have more control, you can e.g. provide an option to set the polling interval.
Describe the problem
I was working on creating user movable applets and came across many scenarios were I needed to reactively have the boundingClientRect of a div. This is not too hard to implement manually but would be really nice to have built into Svelte to avoid the boilerplate.
Describe the proposed solution
Add the ability to bind to the boundingClientRect of an html element using
bind:boundingClientRect
.Importance
nice to have