Redesign fields

This commit is contained in:
Matthias Metelka 2022-08-03 17:47:53 +02:00
parent 4200f35419
commit 3043789960
10 changed files with 176 additions and 83 deletions

View file

@ -189,10 +189,26 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
position: relative;
background: var(--frame-bg);
border-radius: 0 0 5px 5px;
border-radius: 5px;
border: 1px solid var(--border);
&:focus {
box-shadow: 0px 0px 2px 0px var(--border);
transition: box-shadow 80ms cubic-bezier(0.33, 1, 0.68, 1);
&:focus-within {
outline: none;
border-color: var(--focus-border);
&::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
border-radius: 5px;
box-shadow: inset 0 0 0 1px var(--focus-border);
}
}
}
</style>

View file

@ -48,9 +48,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { promiseWithResolver } from "../lib/promise";
import type { Destroyable } from "./destroyable";
import EditingArea from "./EditingArea.svelte";
import FieldState from "./FieldState.svelte";
import LabelContainer from "./LabelContainer.svelte";
import LabelName from "./LabelName.svelte";
export let content: Writable<string>;
export let field: FieldData;
@ -90,14 +87,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:focusout
on:click={() => editingArea.focus?.()}
>
<LabelContainer>
<span>
<LabelName>
{field.name}
</LabelName>
</span>
<FieldState><slot name="field-state" /></FieldState>
</LabelContainer>
<slot name="field-label" />
<EditingArea
{content}
fontFamily={field.fontFamily}
@ -110,16 +101,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<style lang="scss">
.editor-field {
position: relative;
--border-color: var(--border);
border-radius: 5px;
border: 1px solid var(--border-color);
&:focus-within {
--border-color: var(--focus-border);
outline: none;
box-shadow: 0 0 0 3px var(--focus-shadow);
}
}
</style>

View file

@ -11,7 +11,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
display: flex;
justify-content: flex;
flex-grow: 1;
& > :global(*) {
margin-left: 2px;
}

View file

@ -3,35 +3,67 @@ 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 { createEventDispatcher, getContext } from "svelte";
import type { Readable } from "svelte/store";
import { directionKey } from "../lib/context-keys";
import * as tr from "../lib/ftl";
import Badge from "../components/Badge.svelte";
import { chevronRight, chevronDown } from "./icons";
export let off: boolean;
const direction = getContext<Readable<"ltr" | "rtl">>(directionKey);
const dispatch = createEventDispatcher();
function toggle() {
dispatch("toggle");
}
$: icon = off ? chevronRight : chevronDown;
</script>
<div
class:collapsed={off}
class="label-container"
class:rtl={$direction === "rtl"}
on:mousedown|preventDefault
>
<span class="clickable" on:click|stopPropagation={toggle}>
<span class="chevron">
<Badge
tooltip={tr.editingToggleVisualEditor()}
iconSize={80}
--icon-align="text-bottom"
>{@html icon}
</Badge>
</span>
<slot name="field-name" />
</span>
<slot />
</div>
<style lang="scss">
.label-container {
& .chevron {
opacity: 0.4;
transition: opacity 0.2s ease-in-out;
}
display: flex;
justify-content: space-between;
background-color: var(--label-color, transparent);
border-width: 0 0 1px;
border-style: dashed;
border-color: var(--border-color);
border-radius: 5px 5px 0 0;
padding: 0px 6px;
padding: 2px 0;
}
.clickable {
cursor: pointer;
&:hover .chevron {
opacity: 1;
}
}
.rtl {

View file

@ -9,6 +9,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { EditorToolbarAPI } from "./editor-toolbar";
import type { EditorFieldAPI } from "./EditorField.svelte";
import LabelContainer from "./LabelContainer.svelte";
import LabelName from "./LabelName.svelte";
import FieldState from "./FieldState.svelte";
export interface NoteEditorAPI {
fields: EditorFieldAPI[];
focusedField: Writable<EditorFieldAPI | null>;
@ -322,34 +326,30 @@ the AddCards dialog) should be implemented in the user of this component.
? "var(--flag1-bg)"
: "transparent"}
>
<svelte:fragment slot="field-state">
{#if cols[index] === "dupe"}
<DuplicateLink />
{/if}
<RichTextBadge
<svelte:fragment slot="field-label">
<LabelContainer
bind:off={richTextsHidden[index]}
on:toggle={() => {
richTextsHidden[index] = !richTextsHidden[index];
plainTextsHidden[index] = true;
if (!richTextsHidden[index]) {
richTextInputs[index].api.refocus();
}
}}
/>
<PlainTextBadge
bind:off={plainTextsHidden[index]}
on:toggle={() => {
plainTextsHidden[index] = !plainTextsHidden[index];
if (!plainTextsHidden[index]) {
plainTextInputs[index].api.refocus();
}
}}
/>
<slot name="field-state" {field} {index} />
>
<svelte:fragment slot="field-name">
<LabelName>
{field.name}
</LabelName>
</svelte:fragment>
<FieldState>
{#if cols[index] === "dupe"}
<DuplicateLink />
{/if}
<slot name="field-state" {field} {index} />
</FieldState>
</LabelContainer>
</svelte:fragment>
<svelte:fragment slot="editing-inputs">
<RichTextInput
hidden={richTextsHidden[index]}
@ -361,6 +361,20 @@ the AddCards dialog) should be implemented in the user of this component.
>
<ImageHandle maxWidth={250} maxHeight={125} />
<MathjaxHandle />
<svelte:fragment slot="plain-text-badge">
<PlainTextBadge
bind:off={plainTextsHidden[index]}
on:toggle={() => {
plainTextsHidden[index] =
!plainTextsHidden[index];
if (!plainTextsHidden[index]) {
plainTextInputs[index].api.refocus();
}
}}
/>
</svelte:fragment>
</RichTextInput>
<PlainTextInput

View file

@ -5,11 +5,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="ts">
import { createEventDispatcher, onMount } from "svelte";
import Badge from "../components/Badge.svelte";
import * as tr from "../lib/ftl";
import { getPlatformString, registerShortcut } from "../lib/shortcuts";
import { registerShortcut } from "../lib/shortcuts";
import { context as editorFieldContext } from "./EditorField.svelte";
import { htmlOff, htmlOn } from "./icons";
const editorField = editorFieldContext.get();
const keyCombination = "Control+Shift+X";
@ -17,8 +14,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let off = false;
$: icon = off ? htmlOff : htmlOn;
function toggle() {
dispatch("toggle");
}
@ -28,29 +23,72 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
onMount(() => editorField.element.then(shortcut));
let width = 0;
</script>
<span
class="plain-text-badge"
class:highlighted={!off}
<div
class="clickable"
style="--width: {width}px"
on:click|stopPropagation={toggle}
bind:clientWidth={width}
>
<Badge
tooltip="{tr.editingToggleHtmlEditor()} ({getPlatformString(keyCombination)})"
iconSize={80}
--icon-align="text-top">{@html icon}</Badge
>
</span>
<span class:off class:on={!off} class="plain-text-badge" class:highlighted={!off} />
</div>
<style lang="scss">
span {
opacity: 0.4;
&.highlighted {
opacity: 1;
.clickable {
right: calc(50% - var(--width) / 2);
position: absolute;
text-align: center;
bottom: -16px;
z-index: 3;
width: 32px;
height: 16px;
cursor: pointer;
}
&:hover {
opacity: 0.8;
.plain-text-badge {
left: 12px;
position: absolute;
opacity: 0;
width: 8px;
height: 8px;
transform: rotate(-45deg);
transition: bottom 0.2s ease-out;
&.on {
bottom: 0px;
background: var(--code-bg);
border-right: 1px solid var(--border);
border-top: 1px solid var(--border);
}
&.off {
bottom: 10px;
background: var(--frame-bg);
border-left: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
&::before,
&::after {
width: 10px;
height: 10px;
}
}
:global(.editor-field) {
&:hover,
&:focus-within {
& .plain-text-badge {
opacity: 1;
transition: opacity 0.2s ease-in, bottom 0.2s ease-out;
&.on,
&.off {
bottom: 5px;
}
}
}
&:focus-within .plain-text-badge.off {
border-width: 2px;
border-color: var(--focus-border);
}
}
</style>

View file

@ -24,7 +24,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Badge
tooltip={tr.editingToggleVisualEditor()}
iconSize={80}
--icon-align="text-top">{@html icon}</Badge
--icon-align="text-bottom">{@html icon}</Badge
>
</span>

View file

@ -10,12 +10,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import * as tr from "../lib/ftl";
import { getPlatformString, registerShortcut } from "../lib/shortcuts";
import { context as editorFieldContext } from "./EditorField.svelte";
import { stickyOff, stickyOn } from "./icons";
import { stickyIcon } from "./icons";
export let active: boolean;
$: icon = active ? stickyOn : stickyOff;
const editorField = editorFieldContext.get();
const keyCombination = "F9";
@ -38,19 +36,31 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Badge
tooltip="{tr.editingToggleSticky()} ({getPlatformString(keyCombination)})"
widthMultiplier={0.7}
--icon-align="text-top">{@html icon}</Badge
--icon-align="text-bottom">{@html stickyIcon}</Badge
>
</span>
<style lang="scss">
span {
opacity: 0.4;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s ease-in;
&.highlighted {
opacity: 1;
}
}
:global(.editor-field) {
&:focus-within,
&:hover {
& span {
opacity: 0.4;
&:hover {
opacity: 0.8;
}
&.highlighted {
opacity: 1;
}
}
}
}
</style>

View file

@ -164,7 +164,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
:global(.CodeMirror-lines) {
padding: 6px 0;
padding: 8px 0;
}
&.hidden {
@ -172,7 +172,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
.light-theme :global(.CodeMirror) {
border-top: 1px solid #ddd;
:global(.CodeMirror) {
border-top: 1px solid var(--border);
background: var(--code-bg);
}
</style>

View file

@ -238,6 +238,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</div>
{/await}
</RichTextStyles>
<slot name="plain-text-badge" />
</div>
<style lang="scss">