cuire / svelte-grid-extended

A draggable and resizable grid layout, for Svelte
https://svelte-grid-extended.vercel.app
MIT License
78 stars 9 forks source link

[Feature] More control over moving and resizing #21

Closed joakim closed 1 year ago

joakim commented 1 year ago

Is it possible to have more control over moving and resizing of items?

My use case is a "window manager" where each item has a <Titlebar>. I want the contents of the "windows" to be fully interactive (not draggable), and to move a "window" you drag its titlebar. I also want to be able to resize any of the four corners.

Should I fork this great project, or could it be done through configuration and tricks?

cuire commented 1 year ago

That's not possible right now. But it's a cool feature to add.

joakim commented 1 year ago

I'll try forking and having a look at it then. Thanks again for the quick reply!

cuire commented 1 year ago

Adding custom dragger is not difficult.

Styles related to moving must be set in move Start event handler. https://github.com/cuire/svelte-grid-extended/blob/481843ce6adbef15d09bdfb4fa692204c38a55f2/src/lib/GridItem.svelte#L238 And the handler need to be passed to slot like so: https://github.com/cuire/svelte-grid-extended/blob/481843ce6adbef15d09bdfb4fa692204c38a55f2/src/lib/GridItem.svelte#L241

<slot {moveStart} />

Same must be done in Grid component https://github.com/cuire/svelte-grid-extended/blob/481843ce6adbef15d09bdfb4fa692204c38a55f2/src/lib/Grid.svelte#L230-L233

    on:previewchange={updateGridDimensions} 
    let:moveStart 
> 
    <slot {item} {moveStart} /> 
</GridItem> 

And finally it can be used

<Grid {items} cols={10} rows={10} let:moveStart>
    <div>
        <div on:pointerdown={moveStart}>Title<div/>
    </div>
</Grid>

Unfortunately I can't offer a better solution, since <slot> cannot have directives

joakim commented 1 year ago

Nice! Thanks for doing most of the work :)

I only had to add the option to override moveStart()'s if (!movable) return guard, because I had to set movable: false on the items so that the whole item wasn't draggable. I'm sure there's a cleaner way, but it worked.

Use:

<Grid {items} cols={10} rows={10} let:moveStart>
    <div on:pointerdown={(event) => moveStart(event, true)}>Title</div>
</Grid>

https://github.com/cuire/svelte-grid-extended/compare/main...joakim:svelte-grid-extended:main

cuire commented 1 year ago

Done in 1.0.0