Better RTL support

This commit is contained in:
Henrik Giesel 2021-07-21 16:48:02 +02:00 committed by Damien Elmes
parent eb71c97872
commit c6e56e0465
8 changed files with 111 additions and 60 deletions

View File

@ -21,6 +21,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let size: number | undefined = undefined;
export let wrap: boolean | undefined = undefined;
export let reverse = false;
$: buttonSize = size ? `--buttons-size: ${size}rem; ` : "";
let buttonWrap: string;
$: if (wrap === undefined) {
@ -95,7 +97,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div
bind:this={buttonGroupRef}
{id}
class={`btn-group ${className}`}
class="btn-group {className}"
class:reverse
{style}
dir="ltr"
role="group"
@ -110,8 +113,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<style lang="scss">
div {
flex-direction: row;
flex-wrap: var(--buttons-wrap);
padding: calc(var(--buttons-size) / 10);
margin: 0;
}
.reverse {
flex-direction: row-reverse;
}
</style>

View File

@ -18,6 +18,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let iconSize: number = 75;
export let widthMultiplier: number = 1;
export let flipX: boolean = false;
let buttonRef: HTMLButtonElement;
@ -44,7 +45,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:click
on:mousedown|preventDefault
>
<span style={`--width-multiplier: ${widthMultiplier};`}> <slot /> </span>
<span class:flip-x={flipX} style={`--width-multiplier: ${widthMultiplier};`}>
<slot />
</span>
</button>
<style lang="scss">
@ -80,6 +83,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
fill: currentColor;
vertical-align: unset;
}
&.flip-x > :global(svg),
&.flip-x > :global(img) {
transform: scaleX(-1);
}
}
.dropdown-toggle::after {

View File

@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import ImageHandleButtons from "./ImageHandleButtons.svelte";
import ImageHandleFloat from "./ImageHandleFloat.svelte";
import ImageHandleSizeSelect from "./ImageHandleSizeSelect.svelte";
import { getContext } from "svelte";
@ -11,6 +11,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let image: HTMLImageElement | null = null;
export let imageRule: CSSStyleRule | null = null;
export let isRtl: boolean = false;
export let container: HTMLElement;
$: showDimensions = image
@ -37,9 +39,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function updateSizes() {
const imageRect = image!.getBoundingClientRect();
const containerRect = (
container ?? document.documentElement
).getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
naturalWidth = image!.naturalWidth;
naturalHeight = image!.naturalHeight;
@ -100,21 +100,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class="image-handle-selection"
>
<div class="image-handle-bg" on:dblclick={onDblclick} />
<div class="image-handle-buttons">
<ImageHandleButtons bind:float={image.style.float} />
<div class="image-handle-buttons" class:is-rtl={isRtl}>
<ImageHandleFloat {isRtl} bind:float={image.style.float} />
</div>
<div class="image-handle-size-select">
<div class="image-handle-size-select" class:is-rtl={isRtl}>
<ImageHandleSizeSelect
bind:this={sizeSelect}
bind:active
{selector}
{image}
{imageRule}
{selector}
{isRtl}
on:update={updateSizes}
/>
</div>
{#if showDimensions}
<div class="image-handle-dimensions">
<div class="image-handle-dimensions" class:is-rtl={isRtl}>
{width}&times;{height} (Original: {naturalWidth}&times;{naturalHeight})
</div>
{/if}
@ -159,24 +160,40 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.image-handle-buttons {
top: 3px;
left: 3px;
&.is-rtl {
left: auto;
right: 3px;
}
}
.image-handle-size-select {
bottom: 3px;
left: 3px;
&.is-rtl {
left: auto;
right: 3px;
}
}
.image-handle-dimensions {
pointer-events: none;
user-select: none;
bottom: 3px;
right: 3px;
font-size: 13px;
background-color: rgba(0 0 0 / 0.3);
border-color: black;
border-radius: 0.25rem;
padding: 0 5px;
bottom: 3px;
right: 3px;
&.is-rtl {
right: auto;
left: 3px;
}
}
.image-handle-control {

View File

@ -1,44 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import * as tr from "lib/i18n";
import ButtonToolbar from "components/ButtonToolbar.svelte";
import ButtonGroup from "components/ButtonGroup.svelte";
import ButtonGroupItem from "components/ButtonGroupItem.svelte";
import IconButton from "components/IconButton.svelte";
import { floatNoneIcon, floatLeftIcon, floatRightIcon } from "./icons";
export let float: string;
</script>
<ButtonToolbar size={1.6} wrap={false}>
<ButtonGroup>
<ButtonGroupItem>
<IconButton
tooltip={tr.editingFloatNone()}
active={float === "" || float === "none"}
on:click={() => (float = "")}>{@html floatNoneIcon}</IconButton
>
</ButtonGroupItem>
<ButtonGroupItem>
<IconButton
tooltip={tr.editingFloatLeft()}
active={float === "left"}
on:click={() => (float = "left")}>{@html floatLeftIcon}</IconButton
>
</ButtonGroupItem>
<ButtonGroupItem>
<IconButton
tooltip={tr.editingFloatRight()}
active={float === "right"}
on:click={() => (float = "right")}>{@html floatRightIcon}</IconButton
>
</ButtonGroupItem>
</ButtonGroup>
</ButtonToolbar>

View File

@ -0,0 +1,61 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import * as tr from "lib/i18n";
import ButtonGroup from "components/ButtonGroup.svelte";
import ButtonGroupItem from "components/ButtonGroupItem.svelte";
import IconButton from "components/IconButton.svelte";
import { floatNoneIcon, floatLeftIcon, floatRightIcon } from "./icons";
export let float: string;
export let isRtl: boolean;
const leftValues = {
position: "left",
label: tr.editingFloatLeft(),
icon: floatLeftIcon,
};
const rightValues = {
position: "right",
label: tr.editingFloatRight(),
};
$: inlineStart = isRtl ? rightValues : leftValues;
$: inlineEnd = isRtl ? leftValues : rightValues;
</script>
<ButtonGroup size={1.6} wrap={false} reverse={isRtl}>
<ButtonGroupItem>
<IconButton
tooltip={tr.editingFloatNone()}
active={float === "" || float === "none"}
flipX={isRtl}
on:click={() => (float = "")}>{@html floatNoneIcon}</IconButton
>
</ButtonGroupItem>
<ButtonGroupItem>
<IconButton
tooltip={inlineStart.label}
active={float === inlineStart.position}
flipX={isRtl}
on:click={() => (float = inlineStart.position)}
>{@html floatLeftIcon}</IconButton
>
</ButtonGroupItem>
<ButtonGroupItem>
<IconButton
tooltip={inlineEnd.label}
active={float === inlineEnd.position}
flipX={isRtl}
on:click={() => (float = inlineEnd.position)}
>{@html floatRightIcon}</IconButton
>
</ButtonGroupItem>
</ButtonGroup>

View File

@ -16,6 +16,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let imageRule: CSSStyleRule;
export let selector: string;
export let active: boolean;
export let isRtl: boolean;
$: icon = active ? sizeActual : sizeMinimized;
@ -42,6 +43,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<IconButton
{active}
flipX={isRtl}
tooltip={tr.editingActualSize()}
on:click={toggleActualSize}>{@html icon}</IconButton
>

View File

@ -58,8 +58,6 @@ export class EditableContainer extends HTMLDivElement {
}
isRightToLeft(): boolean {
const styleSheet = this.baseStyle.sheet as CSSStyleSheet;
const firstRule = styleSheet.cssRules[0] as CSSStyleRule;
return firstRule.style.direction === "rtl";
return this.baseRule!.style.direction === "rtl";
}
}

View File

@ -171,6 +171,7 @@ export class EditingArea extends HTMLDivElement {
(this.imageHandle as any).$set({
image: event.target,
imageRule: this.editableContainer.imageRule,
isRtl: this.isRightToLeft(),
});
} else {
(this.imageHandle as any).$set({