mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 09:16:38 -04:00
Implement reduced motion mode for Collapsible
This commit is contained in:
parent
26a8c72b4c
commit
654b1db54e
5 changed files with 36 additions and 12 deletions
|
@ -534,6 +534,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
setColorButtons({});
|
setColorButtons({});
|
||||||
setTags({});
|
setTags({});
|
||||||
setMathjaxEnabled({});
|
setMathjaxEnabled({});
|
||||||
|
setReducedMotion({});
|
||||||
""".format(
|
""".format(
|
||||||
json.dumps(data),
|
json.dumps(data),
|
||||||
json.dumps(collapsed),
|
json.dumps(collapsed),
|
||||||
|
@ -545,6 +546,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
|
||||||
json.dumps([text_color, highlight_color]),
|
json.dumps([text_color, highlight_color]),
|
||||||
json.dumps(self.note.tags),
|
json.dumps(self.note.tags),
|
||||||
json.dumps(self.mw.col.get_config("renderMathjax", True)),
|
json.dumps(self.mw.col.get_config("renderMathjax", True)),
|
||||||
|
json.dumps(self.mw.pm.reduced_motion()),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.addMode:
|
if self.addMode:
|
||||||
|
|
|
@ -7,6 +7,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import { tweened } from "svelte/motion";
|
import { tweened } from "svelte/motion";
|
||||||
|
|
||||||
export let duration = 200;
|
export let duration = 200;
|
||||||
|
export let animated = true;
|
||||||
|
|
||||||
function dynamicDuration(height: number, factor: number): number {
|
function dynamicDuration(height: number, factor: number): number {
|
||||||
return 100 + Math.pow(height, 1 / 4) * factor;
|
return 100 + Math.pow(height, 1 / 4) * factor;
|
||||||
|
@ -33,7 +34,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
await new Promise(requestAnimationFrame);
|
await new Promise(requestAnimationFrame);
|
||||||
expandHeight = collapsibleElement.clientHeight;
|
expandHeight = collapsibleElement.clientHeight;
|
||||||
|
|
||||||
animating = true;
|
transitioning = true;
|
||||||
size.set(1, {
|
size.set(1, {
|
||||||
duration: duration || dynamicDuration(expandHeight, 25),
|
duration: duration || dynamicDuration(expandHeight, 25),
|
||||||
easing: cubicIn,
|
easing: cubicIn,
|
||||||
|
@ -42,24 +43,29 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (collapsibleElement) {
|
$: if (collapsibleElement) {
|
||||||
doCollapse(collapse);
|
if (animated) {
|
||||||
|
doCollapse(collapse);
|
||||||
|
} else {
|
||||||
|
collapsed = collapse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let collapsibleElement: HTMLElement;
|
let collapsibleElement: HTMLElement;
|
||||||
|
|
||||||
$: collapsed = $size === 0;
|
$: collapsed = $size === 0;
|
||||||
$: expanded = $size === 1;
|
$: expanded = $size === 1;
|
||||||
$: animating = $size > 0 && !(collapsed || expanded);
|
$: transitioning = $size > 0 && !(collapsed || expanded);
|
||||||
|
|
||||||
$: height = $size * expandHeight;
|
$: height = $size * expandHeight;
|
||||||
$: measuring = !(collapsed || animating || expanded);
|
$: measuring = !(collapsed || transitioning || expanded);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={collapsibleElement}
|
bind:this={collapsibleElement}
|
||||||
class="collapsible"
|
class="collapsible"
|
||||||
class:measuring
|
class:measuring
|
||||||
class:animating
|
class:animated
|
||||||
|
class:transitioning
|
||||||
class:expanded
|
class:expanded
|
||||||
style:--height="{height}px"
|
style:--height="{height}px"
|
||||||
>
|
>
|
||||||
|
@ -72,12 +78,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.collapsible {
|
.collapsible.animated {
|
||||||
&.measuring {
|
&.measuring {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
&.animating {
|
&.transitioning {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
&.expanded {
|
&.expanded {
|
||||||
|
|
|
@ -42,12 +42,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy, setContext } from "svelte";
|
import { getContext, onDestroy, setContext } from "svelte";
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
import Collapsible from "../components/Collapsible.svelte";
|
import Collapsible from "../components/Collapsible.svelte";
|
||||||
import { collapsedKey, directionKey } from "../lib/context-keys";
|
import { collapsedKey, directionKey, reducedMotionKey } from "../lib/context-keys";
|
||||||
import { promiseWithResolver } from "../lib/promise";
|
import { promiseWithResolver } from "../lib/promise";
|
||||||
import type { Destroyable } from "./destroyable";
|
import type { Destroyable } from "./destroyable";
|
||||||
import EditingArea from "./EditingArea.svelte";
|
import EditingArea from "./EditingArea.svelte";
|
||||||
|
@ -67,6 +67,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
$: $collapsedStore = collapsed;
|
$: $collapsedStore = collapsed;
|
||||||
|
|
||||||
|
const reducedMotion = getContext<Readable<boolean>>(reducedMotionKey);
|
||||||
|
|
||||||
const editingArea: Partial<EditingAreaAPI> = {};
|
const editingArea: Partial<EditingAreaAPI> = {};
|
||||||
const [element, elementResolve] = promiseWithResolver<HTMLElement>();
|
const [element, elementResolve] = promiseWithResolver<HTMLElement>();
|
||||||
|
|
||||||
|
@ -88,7 +90,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
<div class="field-container">
|
<div class="field-container">
|
||||||
<slot name="field-label" />
|
<slot name="field-label" />
|
||||||
|
|
||||||
<Collapsible collapse={collapsed} let:collapsed={hidden}>
|
<Collapsible collapse={collapsed} animated={!$reducedMotion} let:collapsed={hidden}>
|
||||||
<div
|
<div
|
||||||
use:elementResolve
|
use:elementResolve
|
||||||
class="editor-field"
|
class="editor-field"
|
||||||
|
|
|
@ -39,13 +39,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, tick } from "svelte";
|
import { onMount, setContext, tick } from "svelte";
|
||||||
import { get, writable } from "svelte/store";
|
import { get, writable } from "svelte/store";
|
||||||
|
|
||||||
import Absolute from "../components/Absolute.svelte";
|
import Absolute from "../components/Absolute.svelte";
|
||||||
import Badge from "../components/Badge.svelte";
|
import Badge from "../components/Badge.svelte";
|
||||||
import StickyContainer from "../components/StickyContainer.svelte";
|
import StickyContainer from "../components/StickyContainer.svelte";
|
||||||
import { bridgeCommand } from "../lib/bridgecommand";
|
import { bridgeCommand } from "../lib/bridgecommand";
|
||||||
|
import { reducedMotionKey } from "../lib/context-keys";
|
||||||
import { TagEditor } from "../tag-editor";
|
import { TagEditor } from "../tag-editor";
|
||||||
import { ChangeTimer } from "./change-timer";
|
import { ChangeTimer } from "./change-timer";
|
||||||
import DecoratedElements from "./DecoratedElements.svelte";
|
import DecoratedElements from "./DecoratedElements.svelte";
|
||||||
|
@ -129,6 +130,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
plainTextDefaults = [...richTextsHidden];
|
plainTextDefaults = [...richTextsHidden];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let reducedMotion = false;
|
||||||
|
function setReducedMotion(enabled: boolean): void {
|
||||||
|
reducedMotion = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reducedMotionStore = writable<boolean>();
|
||||||
|
setContext(reducedMotionKey, reducedMotionStore);
|
||||||
|
$: $reducedMotionStore = reducedMotion;
|
||||||
|
|
||||||
function setMathjaxEnabled(enabled: boolean): void {
|
function setMathjaxEnabled(enabled: boolean): void {
|
||||||
mathjaxConfig.enabled = enabled;
|
mathjaxConfig.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
@ -277,6 +287,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
setNoteId,
|
setNoteId,
|
||||||
wrap,
|
wrap,
|
||||||
setMathjaxEnabled,
|
setMathjaxEnabled,
|
||||||
|
setReducedMotion,
|
||||||
...oldEditorAdapter,
|
...oldEditorAdapter,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -436,6 +447,7 @@ the AddCards dialog) should be implemented in the user of this component.
|
||||||
<svelte:fragment slot="rich-text-input">
|
<svelte:fragment slot="rich-text-input">
|
||||||
<Collapsible
|
<Collapsible
|
||||||
collapse={richTextsHidden[index]}
|
collapse={richTextsHidden[index]}
|
||||||
|
animated={!reducedMotion}
|
||||||
let:collapsed={hidden}
|
let:collapsed={hidden}
|
||||||
>
|
>
|
||||||
<RichTextInput
|
<RichTextInput
|
||||||
|
@ -457,6 +469,7 @@ the AddCards dialog) should be implemented in the user of this component.
|
||||||
<svelte:fragment slot="plain-text-input">
|
<svelte:fragment slot="plain-text-input">
|
||||||
<Collapsible
|
<Collapsible
|
||||||
collapse={plainTextsHidden[index]}
|
collapse={plainTextsHidden[index]}
|
||||||
|
animated={!reducedMotion}
|
||||||
let:collapsed={hidden}
|
let:collapsed={hidden}
|
||||||
>
|
>
|
||||||
<PlainTextInput
|
<PlainTextInput
|
||||||
|
|
|
@ -6,3 +6,4 @@ export const fontSizeKey = Symbol("fontSize");
|
||||||
export const directionKey = Symbol("direction");
|
export const directionKey = Symbol("direction");
|
||||||
export const descriptionKey = Symbol("description");
|
export const descriptionKey = Symbol("description");
|
||||||
export const collapsedKey = Symbol("collapsed");
|
export const collapsedKey = Symbol("collapsed");
|
||||||
|
export const reducedMotionKey = Symbol("reducedMotion");
|
||||||
|
|
Loading…
Reference in a new issue