Fix field description (#1923)

* Remove most of the original description placeholder implementation

* Move description showing logic to RichTextInput

- there is no need to propagate it to ContentEditable

* Remove the @html from field-description

This actually worked - however I removed it in case we'd rather offer
markdown support or something else in the future.

* Do not remove placeholder already on focus

- Other editors do not do it either

* Hide via hidden attribute instead of unmounting

* Do not pass content to ContentEditable

* Sort imports

* Change placeholder text color (dae)

In day mode, slightly-grey is almost indistinguishable from black
(at least on the monitor I'm using here)
This commit is contained in:
Henrik Giesel 2022-06-22 01:53:10 +02:00 committed by GitHub
parent cd3f9ff646
commit c1e54e6842
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 38 deletions

View file

@ -7,11 +7,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</script>
<script lang="ts">
import { getContext } from "svelte";
import type { Readable, Writable } from "svelte/store";
import type { Writable } from "svelte/store";
import { updateAllState } from "../components/WithState.svelte";
import { descriptionKey } from "../lib/context-keys";
import actionList from "../sveltelib/action-list";
import type { MirrorAction } from "../sveltelib/dom-mirror";
import type { SetupInputHandlerAction } from "../sveltelib/input-handler";
@ -35,15 +33,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const [focusHandler, setupFocusHandling] = useFocusHandler();
Object.assign(api, { focusHandler });
const description = getContext<Readable<string>>(descriptionKey);
$: descriptionCSSValue = `"${$description}"`;
export let content: string;
</script>
<anki-editable
class:empty={!content}
contenteditable="true"
use:resolve
use:setupFocusHandling
@ -54,14 +46,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:blur
on:click={updateAllState}
on:keyup={updateAllState}
style="--description: {descriptionCSSValue}"
/>
<style lang="scss">
anki-editable {
display: block;
position: relative;
padding: 6px;
overflow: auto;
overflow-wrap: anywhere;
/* fallback for iOS */
@ -70,17 +61,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
&:focus {
outline: none;
}
&.empty::before {
content: var(--description);
opacity: 0.4;
cursor: text;
/* stay on single line */
position: absolute;
max-width: 95%;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
/* editable-base.scss contains styling targeting user HTML */

View file

@ -47,10 +47,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</script>
<script lang="ts">
import { getAllContexts, onMount } from "svelte";
import { getAllContexts, getContext, onMount } from "svelte";
import type { Readable } from "svelte/store";
import { placeCaretAfterContent } from "../../domlib/place-caret";
import ContentEditable from "../../editable/ContentEditable.svelte";
import {
descriptionKey,
directionKey,
fontFamilyKey,
fontSizeKey,
} from "../../lib/context-keys";
import { promiseWithResolver } from "../../lib/promise";
import { singleCallback } from "../../lib/typing";
import useDOMMirror from "../../sveltelib/dom-mirror";
@ -68,6 +75,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const { focusedInput } = noteEditorContext.get();
const { content, editingInputs } = editingAreaContext.get();
const description = getContext<Readable<string>>(descriptionKey);
const fontFamily = getContext<Readable<string>>(fontFamilyKey);
const fontSize = getContext<Readable<number>>(fontSizeKey);
const direction = getContext<Readable<"ltr" | "rtl">>(directionKey);
const nodes = getNormalizingNodeStore();
const [richTextPromise, resolve] = useRichTextResolve();
const { mirror, preventResubscription } = useDOMMirror();
@ -148,7 +160,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
mirrors: [mirror],
inputHandlers: [setupInputHandler, setupGlobalInputHandler],
api: api.editable,
content: $content,
},
context: allContexts,
});
@ -160,6 +171,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$editingInputs = $editingInputs;
}
function setFocus(): void {
$focusedInput = api;
// We do not unset focusedInput here.
// If we did, UI components for the input would react the store
// being unset, even though most likely it will be set to some other
// field right away.
}
$: pushUpdate(!hidden);
onMount(() => {
@ -180,9 +200,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setupLifecycleHooks(api);
</script>
<div class="rich-text-input" on:focusin={() => ($focusedInput = api)}>
<div class="rich-text-input" on:focusin={setFocus} {hidden}>
{#if $content.length === 0}
<div
class="rich-text-placeholder"
style:font-family={$fontFamily}
style:font-size={$fontSize + "px"}
style:direction={$direction}
>
{$description}
</div>
{/if}
<RichTextStyles
color={$pageTheme.isDark ? "white" : "black"}
fontFamily={$fontFamily}
fontSize={$fontSize}
direction={$direction}
callback={stylesResolve}
let:attachToShadow={attachStyles}
let:stylesDidLoad
@ -190,7 +224,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div
bind:this={richTextDiv}
class={className}
class:hidden
class:night-mode={$pageTheme.isDark}
use:attachShadow
use:attachStyles
@ -208,7 +241,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</div>
<style lang="scss">
.hidden {
display: none;
.rich-text-input {
position: relative;
margin: 6px;
}
.rich-text-placeholder {
position: absolute;
color: var(--disabled);
/* Adopts same size as the content editable element */
width: 100%;
height: 100%;
}
</style>

View file

@ -3,10 +3,6 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { getContext } from "svelte";
import type { Readable } from "svelte/store";
import { directionKey, fontFamilyKey, fontSizeKey } from "../../lib/context-keys";
import { promiseWithResolver } from "../../lib/promise";
import type { StyleLinkType, StyleObject } from "./CustomStyles.svelte";
import CustomStyles from "./CustomStyles.svelte";
@ -25,9 +21,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
});
export let color: string;
const fontFamily = getContext<Readable<string>>(fontFamilyKey);
const fontSize = getContext<Readable<number>>(fontSizeKey);
const direction = getContext<Readable<"ltr" | "rtl">>(directionKey);
export let fontFamily: string;
export let fontSize: number;
export let direction: "ltr" | "rtl";
async function setStyling(property: string, value: unknown): Promise<void> {
const rule = await userBaseRule;
@ -35,9 +31,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
$: setStyling("color", color);
$: setStyling("fontFamily", $fontFamily);
$: setStyling("fontSize", $fontSize + "px");
$: setStyling("direction", $direction);
$: setStyling("fontFamily", fontFamily);
$: setStyling("fontSize", fontSize + "px");
$: setStyling("direction", direction);
const styles = [
{