Improve and unify web dialog styling (#3167)

* Rework ChangeNotetypePage with existing components

* Use disabled Select instead of LabelButton

* Don't use  button for unclickable arrow

* Rework ImportLogPage with existing components

* Improve deck options styling

* Align spacing in ChangeNotetypePage further

* Use StickyContainer on ImportPage

* Format
This commit is contained in:
RumovZ 2024-05-01 09:49:57 +02:00 committed by GitHub
parent 22ac77896f
commit 9418bd9c7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 215 additions and 308 deletions

View file

@ -234,6 +234,7 @@ importing-match-scope-help =
importing-tag-all-notes-help = importing-tag-all-notes-help =
These tags will be added to both newly-imported and updated notes. These tags will be added to both newly-imported and updated notes.
importing-tag-updated-notes-help = These tags will be added to any updated notes. importing-tag-updated-notes-help = These tags will be added to any updated notes.
importing-overview = Overview
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future. ## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.

View file

@ -39,11 +39,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.button-toolbar { .button-toolbar {
flex-wrap: var(--buttons-wrap); flex-wrap: var(--buttons-wrap);
padding-left: 0.15rem; padding-left: 0.15rem;
gap: 1rem;
:global(.button-group) {
/* TODO replace with gap once available */
margin-right: 0.15rem;
margin-bottom: 0.15rem;
}
} }
</style> </style>

View file

@ -8,6 +8,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import LabelButton from "./LabelButton.svelte"; import LabelButton from "./LabelButton.svelte";
import Shortcut from "./Shortcut.svelte"; import Shortcut from "./Shortcut.svelte";
import StickyContainer from "./StickyContainer.svelte";
import ButtonToolbar from "./ButtonToolbar.svelte";
export let path: string; export let path: string;
export let onImport: () => void; export let onImport: () => void;
@ -19,9 +21,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
</script> </script>
<div class="sticky-header d-flex flex-row justify-content-between"> <StickyContainer
--gutter-block="0.5rem"
--gutter-inline="0.25rem"
--sticky-borders="0 0 1px"
breakpoint="sm"
>
<ButtonToolbar class="justify-content-between" wrap={false}>
<div class="filename">{basename(path)}</div> <div class="filename">{basename(path)}</div>
<div class="accept">
<LabelButton <LabelButton
primary primary
tooltip={getPlatformString(keyCombination)} tooltip={getPlatformString(keyCombination)}
@ -32,26 +39,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div class="import">{tr.actionsImport()}</div> <div class="import">{tr.actionsImport()}</div>
</LabelButton> </LabelButton>
<Shortcut {keyCombination} on:action={onImport} /> <Shortcut {keyCombination} on:action={onImport} />
</div> </ButtonToolbar>
</div> </StickyContainer>
<style lang="scss"> <style lang="scss">
.sticky-header {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
margin: 0;
padding: 0.5rem;
background: var(--canvas);
border-bottom: 1px solid var(--border);
.import { .import {
margin-inline: 0.75rem; margin: 0.2rem 0.75rem;
}
} }
.filename { .filename {

View file

@ -55,10 +55,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
h1 { h1 {
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--border);
padding-bottom: 0.25em;
} }
.help-badge { .help-badge {
right: 0; right: 0;
bottom: 12px; top: 0;
color: #555; color: #555;
&.rtl { &.rtl {
right: unset; right: unset;

View file

@ -33,7 +33,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div <div
class="outer" class="outer"
style="--container-height: {containerHeight + 1}px" style="--container-height: {containerHeight}px"
bind:this={container} bind:this={container}
on:scroll={() => (scrollTop = container.scrollTop)} on:scroll={() => (scrollTop = container.scrollTop)}
> >
@ -67,7 +67,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
width: 100%; width: 100%;
overflow: auto; overflow: auto;
height: var(--container-height); max-height: var(--container-height);
margin: 0 auto; margin: 0 auto;
} }

View file

@ -6,10 +6,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import { renderMarkdown } from "@tslib/helpers"; import { renderMarkdown } from "@tslib/helpers";
import Col from "$lib/components/Col.svelte";
import Container from "$lib/components/Container.svelte"; import Container from "$lib/components/Container.svelte";
import Row from "$lib/components/Row.svelte"; import Row from "$lib/components/Row.svelte";
import StickyContainer from "$lib/components/StickyContainer.svelte"; import StickyContainer from "$lib/components/StickyContainer.svelte";
import TitledContainer from "$lib/components/TitledContainer.svelte";
import type { ChangeNotetypeState } from "./lib"; import type { ChangeNotetypeState } from "./lib";
import { MapContext } from "./lib"; import { MapContext } from "./lib";
@ -19,31 +19,30 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let state: ChangeNotetypeState; export let state: ChangeNotetypeState;
$: info = state.info; $: info = state.info;
let offset: number;
</script> </script>
<div bind:offsetHeight={offset}>
<StickyContainer <StickyContainer
--gutter-block="0.1rem" --gutter-block="0.5rem"
--gutter-inline="0.25rem" --gutter-inline="0.25rem"
--sticky-borders="0 0 1px" --sticky-borders="0 0 1px"
--z-index="4" breakpoint="sm"
> >
<NotetypeSelector {state} /> <NotetypeSelector {state} />
</StickyContainer> </StickyContainer>
</div>
<div id="scrollArea" style="--offset: {offset}px; --gutter-inline: 0.25rem;"> <Container breakpoint="sm" --gutter-inline="0.25rem" --gutter-block="0.75rem">
<Row class="gx-0" --cols={2}> <Row --cols={2}>
<Col --col-size={1} breakpoint="md"> <TitledContainer title={tr.changeNotetypeFields()}>
<Container> <Row>
<StickyHeader {state} ctx={MapContext.Field} --z-index="2" /> <StickyHeader {state} ctx={MapContext.Field} />
<Mapper {state} ctx={MapContext.Field} /> <Mapper {state} ctx={MapContext.Field} />
</Container> </Row>
</Col> </TitledContainer>
<Col --col-size={1} breakpoint="md"> </Row>
<Container> <Row --cols={2}>
<StickyHeader {state} ctx={MapContext.Template} --z-index="2" /> <TitledContainer title={tr.changeNotetypeTemplates()}>
<Row>
<StickyHeader {state} ctx={MapContext.Template} />
{#if $info.templates} {#if $info.templates}
<Mapper {state} ctx={MapContext.Template} /> <Mapper {state} ctx={MapContext.Template} />
{:else} {:else}
@ -51,15 +50,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{@html renderMarkdown(tr.changeNotetypeToFromCloze())} {@html renderMarkdown(tr.changeNotetypeToFromCloze())}
</div> </div>
{/if} {/if}
</Container>
</Col>
</Row> </Row>
</div> </TitledContainer>
</Row>
<style> </Container>
#scrollArea {
padding: 0;
overflow: hidden auto;
height: calc(100% - var(--offset));
}
</style>

View file

@ -3,11 +3,9 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="ts"> <script lang="ts">
import Badge from "$lib/components/Badge.svelte";
import ButtonToolbar from "$lib/components/ButtonToolbar.svelte"; import ButtonToolbar from "$lib/components/ButtonToolbar.svelte";
import Icon from "$lib/components/Icon.svelte"; import Icon from "$lib/components/Icon.svelte";
import { arrowLeftIcon, arrowRightIcon } from "$lib/components/icons"; import { arrowLeftIcon, arrowRightIcon } from "$lib/components/icons";
import LabelButton from "$lib/components/LabelButton.svelte";
import Select from "$lib/components/Select.svelte"; import Select from "$lib/components/Select.svelte";
import type { ChangeNotetypeState } from "./lib"; import type { ChangeNotetypeState } from "./lib";
@ -25,17 +23,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</script> </script>
<ButtonToolbar class="justify-content-between" wrap={false}> <ButtonToolbar class="justify-content-between" wrap={false}>
<LabelButton ellipsis disabled={true}> <div class="d-flex flex-row w-100">
{$info.oldNotetypeName} <Select label={$info.oldNotetypeName} value={1} list={[1]} disabled={true} />
</LabelButton> <div class="arrow-container">
<Badge iconSize={70}>
{#if window.getComputedStyle(document.body).direction == "rtl"} {#if window.getComputedStyle(document.body).direction == "rtl"}
<Icon icon={arrowLeftIcon} /> <Icon icon={arrowLeftIcon} />
{:else} {:else}
<Icon icon={arrowRightIcon} /> <Icon icon={arrowRightIcon} />
{/if} {/if}
</Badge> </div>
<Select class="flex-grow-1" list={options} bind:value {label} /> <Select list={options} bind:value {label} />
</div>
<SaveButton {state} /> <SaveButton {state} />
</ButtonToolbar> </ButtonToolbar>
<style lang="scss">
.arrow-container {
margin: 0 0.5em;
}
</style>

View file

@ -5,13 +5,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="ts"> <script lang="ts">
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import Badge from "$lib/components/Badge.svelte";
import Col from "$lib/components/Col.svelte"; import Col from "$lib/components/Col.svelte";
import Container from "$lib/components/Container.svelte"; import Container from "$lib/components/Container.svelte";
import Icon from "$lib/components/Icon.svelte";
import { exclamationIcon } from "$lib/components/icons";
import Row from "$lib/components/Row.svelte"; import Row from "$lib/components/Row.svelte";
import StickyContainer from "$lib/components/StickyContainer.svelte";
import Alert from "./Alert.svelte"; import Alert from "./Alert.svelte";
import type { ChangeNotetypeState } from "./lib"; import type { ChangeNotetypeState } from "./lib";
@ -22,34 +18,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: info = state.info; $: info = state.info;
const heading: string =
ctx === MapContext.Field
? tr.changeNotetypeFields()
: tr.changeNotetypeTemplates();
$: unused = $: unused =
$info.isCloze && ctx === MapContext.Template ? [] : $info.unusedItems(ctx); $info.isCloze && ctx === MapContext.Template ? [] : $info.unusedItems(ctx);
</script> </script>
<StickyContainer
--sticky-top={ctx === MapContext.Template ? "-1px" : "0"}
--sticky-border="var(--border)"
--sticky-borders="0px 0 1px"
>
<h1>
{heading}
{#if unused.length > 0}
<Badge iconSize={80}>
<Icon icon={exclamationIcon} />
</Badge>
{/if}
</h1>
{#if unused.length > 0} {#if unused.length > 0}
<Alert {unused} {ctx} /> <Alert {unused} {ctx} />
{/if} {/if}
{#if $info.templates} {#if $info.templates || ctx === MapContext.Field}
<Container --gutter-inline="0.5rem" --gutter-block="0.2rem"> <Container --gutter-inline="0.5rem" --gutter-block="0.2rem">
<Row --cols={2}> <Row --cols={2}>
<Col --col-size={1}><b>{tr.changeNotetypeCurrent()}</b></Col> <Col --col-size={1}><b>{tr.changeNotetypeCurrent()}</b></Col>
@ -57,10 +34,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</Row> </Row>
</Container> </Container>
{/if} {/if}
</StickyContainer>
<style lang="scss">
h1 {
padding-top: 0.5em;
}
</style>

View file

@ -75,6 +75,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let showFloating = false; let showFloating = false;
</script> </script>
<div class="d-flex">
<LabelButton <LabelButton
primary primary
on:click={() => save(UpdateDeckConfigsMode.NORMAL)} on:click={() => save(UpdateDeckConfigsMode.NORMAL)}
@ -119,14 +120,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{tr.deckConfigRemoveGroup()} {tr.deckConfigRemoveGroup()}
</DropdownItem> </DropdownItem>
<DropdownDivider /> <DropdownDivider />
<DropdownItem on:click={() => save(UpdateDeckConfigsMode.APPLY_TO_CHILDREN)}> <DropdownItem
on:click={() => save(UpdateDeckConfigsMode.APPLY_TO_CHILDREN)}
>
{tr.deckConfigSaveToAllSubdecks()} {tr.deckConfigSaveToAllSubdecks()}
</DropdownItem> </DropdownItem>
<DropdownItem on:click={() => save(UpdateDeckConfigsMode.COMPUTE_ALL_WEIGHTS)}> <DropdownItem
on:click={() => save(UpdateDeckConfigsMode.COMPUTE_ALL_WEIGHTS)}
>
{tr.deckConfigSaveAndOptimize()} {tr.deckConfigSaveAndOptimize()}
</DropdownItem> </DropdownItem>
</Popover> </Popover>
</WithFloating> </WithFloating>
</div>
<style lang="scss"> <style lang="scss">
.save { .save {

View file

@ -57,7 +57,7 @@
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: space-between; justify-content: space-between;
padding-inline: 0; padding-inline: 0;
margin-bottom: 0.25rem; margin-bottom: 0.5rem;
list-style: none; list-style: none;
} }
@ -75,7 +75,6 @@
li.active > button { li.active > button {
color: var(--fg); color: var(--fg);
border-bottom: 4px solid var(--border-focus); border-bottom: 4px solid var(--border-focus);
margin-bottom: -2px;
border-radius: 0; border-radius: 0;
} }
button:hover { button:hover {

View file

@ -1,53 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import * as tr from "@generated/ftl";
import { bridgeCommand } from "@tslib/bridgecommand";
import { getPlatformString } from "@tslib/shortcuts";
import LabelButton from "$lib/components/LabelButton.svelte";
import Shortcut from "$lib/components/Shortcut.svelte";
export let container: HTMLElement;
const keyCombination = "Control+Enter";
function onClose() {
bridgeCommand("close");
}
</script>
<div
class="fixed-header d-flex flex-row-reverse justify-content-between desktop-only"
bind:this={container}
>
<LabelButton
primary
tooltip={getPlatformString(keyCombination)}
on:click={onClose}
--border-left-radius="5px"
--border-right-radius="5px"
>
<div class="close">{tr.actionsClose()}</div>
</LabelButton>
<Shortcut {keyCombination} on:action={onClose} />
</div>
<style lang="scss">
.fixed-header {
position: fixed;
right: 0;
bottom: 0;
z-index: 10;
margin: 0;
padding: 0.5rem;
background: var(--canvas);
.close {
margin-inline: 0.75rem;
}
}
</style>

View file

@ -17,16 +17,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let summaries: SummarizedLogQueues[]; export let summaries: SummarizedLogQueues[];
export let bottomOffset: number = 0; export let bottomOffset: number = 0;
let bottom: HTMLElement;
$: rows = getRows(summaries); $: rows = getRows(summaries);
</script> </script>
<details> <div bind:this={bottom}>
<summary>{tr.importingDetails()}</summary> {#if bottom}
<VirtualTable <VirtualTable
class="details-table" class="details-table"
itemHeight={50} itemHeight={40}
itemsCount={rows.length} itemsCount={rows.length}
bind:bottomOffset {bottomOffset}
> >
<tr slot="headers"> <tr slot="headers">
<th>#</th> <th>#</th>
@ -65,7 +66,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</tr> </tr>
</svelte:fragment> </svelte:fragment>
</VirtualTable> </VirtualTable>
</details> {/if}
</div>
<style lang="scss"> <style lang="scss">
:global(.details-table) { :global(.details-table) {
@ -77,11 +79,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
background: transparent !important; background: transparent !important;
} }
tr { tr {
height: 50px; height: 40px;
text-align: center; text-align: center;
} }
.index-cell { .index-cell {
width: 6em; width: 3em;
} }
:global(.status-cell) { :global(.status-cell) {
width: 5em; width: 5em;
@ -90,7 +92,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
text-align: left; text-align: left;
} }
:global(.search-cell) { :global(.search-cell) {
width: 4em; width: 3em;
} }
} }
</style> </style>

View file

@ -7,47 +7,46 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import Container from "$lib/components/Container.svelte"; import Container from "$lib/components/Container.svelte";
import Row from "$lib/components/Row.svelte";
import TitledContainer from "$lib/components/TitledContainer.svelte";
import CloseButton from "./CloseButton.svelte";
import DetailsTable from "./DetailsTable.svelte"; import DetailsTable from "./DetailsTable.svelte";
import { getSummaries } from "./lib"; import { getSummaries } from "./lib";
import QueueSummary from "./QueueSummary.svelte"; import QueueSummary from "./QueueSummary.svelte";
export let response: ImportResponse; export let response: ImportResponse;
const result = response; $: summaries = getSummaries(response.log!);
$: summaries = result ? getSummaries(result.log!) : []; $: foundNotes = response.log?.foundNotes ?? 0;
$: foundNotes = result?.log?.foundNotes ?? 0;
let closeButton: HTMLElement; const gutterBlockSize = 0.5;
const computedStyle = getComputedStyle(document.documentElement);
const rootFontSize = parseInt(computedStyle.fontSize);
// Container padding + Row padding + Row margin + TitledContainer padding
const bottomOffset = (3 * gutterBlockSize + 0.75) * rootFontSize;
</script> </script>
<Container class="import-log-page"> <Container
{#if result} breakpoint="sm"
<p class="note-count"> --gutter-inline="0.25rem"
--gutter-block={`${gutterBlockSize}rem`}
>
<Row>
<TitledContainer title={tr.importingOverview()}>
<p>
{tr.importingNotesFoundInFile2({ {tr.importingNotesFoundInFile2({
notes: foundNotes, notes: foundNotes,
})} })}
</p> </p>
<ul class="summary-list"> <ul>
{#each summaries as summary} {#each summaries as summary}
<QueueSummary {summary} /> <QueueSummary {summary} />
{/each} {/each}
</ul> </ul>
{#if closeButton} </TitledContainer>
<DetailsTable {summaries} bind:bottomOffset={closeButton.clientHeight} /> </Row>
{/if} <Row>
<CloseButton bind:container={closeButton} /> <TitledContainer title={tr.importingDetails()}>
{/if} <DetailsTable {summaries} {bottomOffset} />
</TitledContainer>
</Row>
</Container> </Container>
<style lang="scss">
:global(.import-log-page) {
font-size: 16px;
margin: 8px auto;
}
.note-count {
margin-bottom: 4px;
}
.summary-list {
padding-inline-start: 8px;
}
</style>

View file

@ -47,7 +47,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Container <Container
breakpoint="sm" breakpoint="sm"
--gutter-inline="0.25rem" --gutter-inline="0.25rem"
--gutter-block="0.75rem" --gutter-block="0.5rem"
class="container-columns" class="container-columns"
> >
<slot /> <slot />