Fix automatic positioning of ButtonDropdown after changing float property

This commit is contained in:
Henrik Giesel 2021-08-06 03:53:44 +02:00 committed by Damien Elmes
parent 3579b6a3b6
commit cc2641095f
4 changed files with 79 additions and 25 deletions

View file

@ -8,27 +8,51 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { setContext, onDestroy } from "svelte"; import { setContext, onDestroy } from "svelte";
import { dropdownKey } from "./context-keys"; import { dropdownKey } from "./context-keys";
export let autoOpen = false;
export let autoClose: boolean | "inside" | "outside" = true;
export let placement = "bottom-start";
setContext(dropdownKey, { setContext(dropdownKey, {
dropdown: true, dropdown: true,
"data-bs-toggle": "dropdown", "data-bs-toggle": "dropdown",
}); });
let dropdown: Dropdown; let dropdown: Dropdown;
let dropdownObject: Dropdown;
const noop = () => {}; const noop = () => {};
function createDropdown(toggle: HTMLElement): Dropdown { function createDropdown(toggle: HTMLElement): Dropdown {
/* avoid focusing element toggle on menu activation */ /* avoid focusing element toggle on menu activation */
toggle.focus = noop; toggle.focus = noop;
dropdown = new Dropdown(toggle, {} as any); dropdown = new Dropdown(toggle, {
autoClose,
popperConfig: (defaultConfig: Record<string, any>) => ({
...defaultConfig,
placement,
}),
} as any);
return dropdown; if (autoOpen) {
dropdown.show();
}
dropdownObject = {
show: dropdown.show.bind(dropdown),
toggle: dropdown.toggle.bind(dropdown),
hide: dropdown.hide.bind(dropdown),
update: dropdown.update.bind(dropdown),
dispose: dropdown.dispose.bind(dropdown),
};
return dropdownObject;
} }
onDestroy(() => dropdown?.dispose()); onDestroy(() => dropdown?.dispose());
</script> </script>
<div class="dropdown"> <div class="dropdown">
<slot {createDropdown} dropdownObject={dropdown} /> <slot {createDropdown} {dropdownObject} />
</div> </div>
<style lang="scss"> <style lang="scss">

View file

@ -31,6 +31,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:active class:active
class="nw" class="nw"
on:mousedown|preventDefault on:mousedown|preventDefault
on:click
on:pointerdown={onPointerdown(true, true)} on:pointerdown={onPointerdown(true, true)}
on:pointerup on:pointerup
on:pointermove on:pointermove
@ -40,6 +41,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:active class:active
class="ne" class="ne"
on:mousedown|preventDefault on:mousedown|preventDefault
on:click
on:pointerdown={onPointerdown(true, false)} on:pointerdown={onPointerdown(true, false)}
on:pointerup on:pointerup
on:pointermove on:pointermove
@ -49,6 +51,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:active class:active
class="sw" class="sw"
on:mousedown|preventDefault on:mousedown|preventDefault
on:click
on:pointerdown={onPointerdown(false, true)} on:pointerdown={onPointerdown(false, true)}
on:pointerup on:pointerup
on:pointermove on:pointermove
@ -58,6 +61,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:active class:active
class="se" class="se"
on:mousedown|preventDefault on:mousedown|preventDefault
on:click
on:pointerdown={onPointerdown(false, false)} on:pointerdown={onPointerdown(false, false)}
on:pointerup on:pointerup
on:pointermove on:pointermove

View file

@ -133,24 +133,31 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
activeImage!.width = width; activeImage!.width = width;
await updateSizesWithDimensions();
} }
onDestroy(() => resizeObserver.disconnect()); onDestroy(() => resizeObserver.disconnect());
</script> </script>
{#if sheet} {#if sheet}
<WithImageConstrained <WithDropdown
{sheet} placement="bottom"
{container} autoOpen={true}
{activeImage} autoClose={false}
on:update={updateSizesWithDimensions} let:createDropdown
let:toggleActualSize let:dropdownObject
let:active
> >
{#if activeImage} <WithImageConstrained
<WithDropdown let:createDropdown> {sheet}
{container}
{activeImage}
on:update={() => {
updateSizesWithDimensions();
dropdownObject.update();
}}
let:toggleActualSize
let:active
>
{#if activeImage}
<HandleSelection <HandleSelection
bind:updateSelection bind:updateSelection
{container} {container}
@ -158,8 +165,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:mount={(event) => createDropdown(event.detail.selection)} on:mount={(event) => createDropdown(event.detail.selection)}
> >
<HandleBackground <HandleBackground
on:click={(event) => event.stopPropagation()}
on:dblclick={toggleActualSize} on:dblclick={toggleActualSize}
on:mount={(event) => createDropdown(event.detail.background)}
/> />
<HandleLabel {isRtl} on:mount={updateDimensions}> <HandleLabel {isRtl} on:mount={updateDimensions}>
@ -175,19 +182,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
activeSize={7} activeSize={7}
offsetX={5} offsetX={5}
offsetY={5} offsetY={5}
on:click={(event) => event.stopPropagation()}
on:pointerclick={(event) => { on:pointerclick={(event) => {
if (active) { if (active) {
setPointerCapture(event); setPointerCapture(event);
} }
}} }}
on:pointerup={startObserving} on:pointerup={startObserving}
on:pointermove={resize} on:pointermove={(event) => {
resize(event);
updateSizesWithDimensions();
dropdownObject.update();
}}
/> />
</HandleSelection> </HandleSelection>
<ButtonDropdown> <ButtonDropdown>
<div on:click={updateSizesWithDimensions}> <div on:click={updateSizesWithDimensions}>
<Item> <Item>
<ImageHandleFloat image={activeImage} {isRtl} /> <ImageHandleFloat
image={activeImage}
{isRtl}
on:update={dropdownObject.update}
/>
</Item> </Item>
<Item> <Item>
<ImageHandleSizeSelect <ImageHandleSizeSelect
@ -198,7 +214,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</Item> </Item>
</div> </div>
</ButtonDropdown> </ButtonDropdown>
</WithDropdown> {/if}
{/if} </WithImageConstrained>
</WithImageConstrained> </WithDropdown>
{/if} {/if}

View file

@ -9,6 +9,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ButtonGroupItem from "components/ButtonGroupItem.svelte"; import ButtonGroupItem from "components/ButtonGroupItem.svelte";
import IconButton from "components/IconButton.svelte"; import IconButton from "components/IconButton.svelte";
import { createEventDispatcher } from "svelte";
import { floatNoneIcon, floatLeftIcon, floatRightIcon } from "./icons"; import { floatNoneIcon, floatLeftIcon, floatRightIcon } from "./icons";
export let image: HTMLImageElement; export let image: HTMLImageElement;
@ -27,6 +28,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: inlineStart = isRtl ? rightValues : leftValues; $: inlineStart = isRtl ? rightValues : leftValues;
$: inlineEnd = isRtl ? leftValues : rightValues; $: inlineEnd = isRtl ? leftValues : rightValues;
const dispatch = createEventDispatcher();
</script> </script>
<ButtonGroup size={1.6} wrap={false} reverse={isRtl}> <ButtonGroup size={1.6} wrap={false} reverse={isRtl}>
@ -35,7 +38,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={tr.editingFloatNone()} tooltip={tr.editingFloatNone()}
active={image.style.float === "" || image.style.float === "none"} active={image.style.float === "" || image.style.float === "none"}
flipX={isRtl} flipX={isRtl}
on:click={() => (image.style.float = "")}>{@html floatNoneIcon}</IconButton on:click={() => {
image.style.float = "";
setTimeout(() => dispatch("update"));
}}>{@html floatNoneIcon}</IconButton
> >
</ButtonGroupItem> </ButtonGroupItem>
@ -44,8 +50,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={inlineStart.label} tooltip={inlineStart.label}
active={image.style.float === inlineStart.position} active={image.style.float === inlineStart.position}
flipX={isRtl} flipX={isRtl}
on:click={() => (image.style.float = inlineStart.position)} on:click={() => {
>{@html floatLeftIcon}</IconButton image.style.float = inlineStart.position;
setTimeout(() => dispatch("update"));
}}>{@html floatLeftIcon}</IconButton
> >
</ButtonGroupItem> </ButtonGroupItem>
@ -54,8 +62,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={inlineEnd.label} tooltip={inlineEnd.label}
active={image.style.float === inlineEnd.position} active={image.style.float === inlineEnd.position}
flipX={isRtl} flipX={isRtl}
on:click={() => (image.style.float = inlineEnd.position)} on:click={() => {
>{@html floatRightIcon}</IconButton image.style.float = inlineEnd.position;
setTimeout(() => dispatch("update"));
}}>{@html floatRightIcon}</IconButton
> >
</ButtonGroupItem> </ButtonGroupItem>
</ButtonGroup> </ButtonGroup>