mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00

* Adjust size of legacy buttons * Revert "Adjust size of legacy buttons" This reverts commitfb888fe1db
. * Remove unused function from #1476 * Use outline version for tag icon * Add chevron icons * Remove code icons, keep one pin icon version * Add code-bg color * Redesign fields * Remove unused import * Fix imports * Move PlainTextBadge between editing inputs where it belongs :) * Make whole separator line clickable * Fix transition and format * Don't show toggle when field is collapsed * Show toggle only on hover for mobile I'd like to implement a swipe mechanism. * Use tweened SVG for triangle instead of CSS hack * Implement more obvious HTML toggle on bottom right * Reduce field height by a few pixels * Reduce field height by two pixels * Show HTML toggle when PlainTextInput is active, regardless of hover/focus * Remove RichTextBadge.svelte * Create separate collapsed field state this means users can collapse fields with the HTML editor open and it will stay open when the field is expanded again. * Add slide out animation to EditingArea, RichTextInput and PlainTextInput only for collapsing, because it is choppy on expansion (common issue with Svelte transitions). * Fix aliasing issue on focused field corners * Make StickyBadge feel more responsive * Move StickyBadge closer to field border * Adjust field gutter/margins * Make LabelContainer sticky to make field operations accessible on fields with a lot of content. * Add back html icons, remove visual editor icons * Revert "Add code-bg color" This reverts commit4200f35419
. * Add rich text icon, remove strikethrough code icon * Revert PlainTextBadge to original position * Adjust margins in FieldState * Rename PlainTextBadge to SecondaryInputBadge in preparation for #1987 * Run eslint and prettier * Make whole LabelContainer clickable area for collapse/expand * Revert "Add slide out animation to EditingArea, RichTextInput and PlainTextInput" This reverts commit9a2b3410d0
. * Fix error on collapse/expansion this was caused by the {#if} blocks, which resulted in the deletion of original EditingAreas. * Refocus when toggling chevron and secondary input badge * Revert "Revert "Add code-bg color"" This reverts commit1cfd3bda65
. * Use single rotating chevron icon and make it RTL-compatible * Remove redundant CSS transition rule * Introduce animated Collapsible component and fix refocus on toggle * Do not try to force repaint, as it is not required * Remove RTL store from LabelContainer the direction is already applied globally. * Collapse secondary input with field * Add focusedField to NoteEditorAPI * Replace :global CSS selector with class .visible thus removing the assumption that the component is used inside an EditorField. https://github.com/ankitects/anki/pull/2002#discussion_r944876448 * Use named function syntax instead of function expressions * Add explanation comment * Remove unnecessary :bind directive * Create CollapseBadge component * Move :global selector into .plain-text-input * Add comment explaining box-shadow pseudo-element * Move Collapsible from EditingArea, PlainTextInput and RichTextInput into user components * Rename SecondaryInputBadge to PlainTextBadge and remove generalization logic I kept the rich text icon inside icons.ts for future use. * Sort imports * Fix background-color for duplicates not showing with yet another pseudo-element :) The pseudo-element that covers up field borders on scroll caused this issue. Fighting fire with fire here. * Increase size of plain text toggle to original value again This makes the clickable area a bit bigger and looks slightly more consistent with StickyBadge. * Scrap pseudo-element mess in LabelContainer and tackle the actual issue * Add class .visible to StickyBadge too This introduces a peculiar bug: The active prop of StickyBadge resets to false when the mouse leaves the field - regardless of the actual back-end value. * Fix sticky badge resetting on mouseleave/blur * Apply overflow: hidden only during transition fixes MathJax handle getting cut off by fields * Remove unused variable * Fix visual bug caused by overflow:hidden not applying in time I tried several asynchronous approaches, but they all caused issues: either they prevented the CSS transition or they made field inputs lose focus. In the end I resorted to direct, synchronous DOM-manipulation and added an explanatory comment. * Decrease Collapsible load time by blocking first transition I noticed the sliding animation has a hefty performance impact when a large number of fields is loaded simultaneously. Blocking the first transition (which isn't even visible) results in a big boost in load time. * Replace usages of gap with margins for children * Revert unnecessary removal of grid-gap definition * Correct comments about flex-gap property mistook that for grid-gap. * Resolve style issues * Add minimum targets to gap comment Co-authored-by: Henrik Giesel <hengiesel@gmail.com>
100 lines
2.7 KiB
Svelte
100 lines
2.7 KiB
Svelte
<!--
|
|
Copyright: Ankitects Pty Ltd and contributors
|
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
-->
|
|
<script lang="ts">
|
|
import { promiseWithResolver } from "../lib/promise";
|
|
|
|
export let id: string | undefined = undefined;
|
|
let className: string = "";
|
|
export { className as class };
|
|
|
|
export let collapsed = false;
|
|
|
|
const [outerPromise, outerResolve] = promiseWithResolver<HTMLElement>();
|
|
const [innerPromise, innerResolve] = promiseWithResolver<HTMLElement>();
|
|
|
|
let isCollapsed = false;
|
|
|
|
let style: string;
|
|
function setStyle(height: number, duration: number) {
|
|
style = `--collapse-height: -${height}px; --duration: ${duration}ms`;
|
|
}
|
|
|
|
/* The following two functions use synchronous DOM-manipulation,
|
|
because Editor field inputs would lose focus when using tick() */
|
|
|
|
function getRequiredHeight(el: HTMLElement): number {
|
|
el.style.setProperty("position", "absolute");
|
|
el.style.setProperty("visibility", "hidden");
|
|
el.removeAttribute("hidden");
|
|
|
|
const height = el.clientHeight;
|
|
|
|
el.setAttribute("hidden", "");
|
|
el.style.removeProperty("position");
|
|
el.style.removeProperty("visibility");
|
|
|
|
return height;
|
|
}
|
|
|
|
async function transition(collapse: boolean) {
|
|
const outer = await outerPromise;
|
|
const inner = await innerPromise;
|
|
|
|
outer.style.setProperty("overflow", "hidden");
|
|
isCollapsed = true;
|
|
|
|
const height = collapse ? inner.clientHeight : getRequiredHeight(inner);
|
|
const duration = Math.sqrt(height * 80);
|
|
|
|
setStyle(height, duration);
|
|
|
|
if (!collapse) {
|
|
inner.removeAttribute("hidden");
|
|
isCollapsed = false;
|
|
}
|
|
|
|
inner.addEventListener(
|
|
"transitionend",
|
|
() => {
|
|
inner.toggleAttribute("hidden", collapse);
|
|
outer.style.removeProperty("overflow");
|
|
},
|
|
{ once: true },
|
|
);
|
|
}
|
|
|
|
/* prevent transition on mount for performance reasons */
|
|
let blockTransition = true;
|
|
|
|
$: if (blockTransition) {
|
|
blockTransition = false;
|
|
} else {
|
|
transition(collapsed);
|
|
}
|
|
</script>
|
|
|
|
<div {id} class="collapsible-container {className}" use:outerResolve>
|
|
<div
|
|
class="collapsible-inner"
|
|
class:collapsed={isCollapsed}
|
|
use:innerResolve
|
|
{style}
|
|
>
|
|
<slot />
|
|
</div>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
.collapsible-container {
|
|
position: relative;
|
|
}
|
|
.collapsible-inner {
|
|
transition: margin-top var(--duration) ease-in;
|
|
|
|
&.collapsed {
|
|
margin-top: var(--collapse-height);
|
|
}
|
|
}
|
|
</style>
|