mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Fix automatic positioning of ButtonDropdown after changing float property
This commit is contained in:
parent
3579b6a3b6
commit
cc2641095f
4 changed files with 79 additions and 25 deletions
|
@ -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">
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue