mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
WIP: Use our components in deckoptions sticky bar
This commit is contained in:
parent
a8b1291f84
commit
e5d11ac547
13 changed files with 115 additions and 92 deletions
|
@ -9,7 +9,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import WithTheming from "./WithTheming.svelte";
|
||||
import ButtonToolbar from "./ButtonToolbar.svelte";
|
||||
|
||||
export let id: string | undefined;
|
||||
export let id: string;
|
||||
let className = "";
|
||||
export { className as class };
|
||||
|
||||
|
|
5
ts/components/DropdownDivider.svelte
Normal file
5
ts/components/DropdownDivider.svelte
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!--
|
||||
Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<hr class="dropdown-divider" />
|
|
@ -6,7 +6,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import { setContext } from "svelte";
|
||||
import { dropdownKey } from "./contextKeys";
|
||||
|
||||
export let id: string | undefined;
|
||||
export let id: string;
|
||||
|
||||
setContext(dropdownKey, null);
|
||||
</script>
|
||||
|
|
|
@ -11,6 +11,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
export let id: string | undefined = undefined;
|
||||
let className: string = "";
|
||||
export { className as class };
|
||||
export let theme = "anki";
|
||||
|
||||
function extendClassName(className: string, theme: string): string {
|
||||
return `btn ${theme !== "anki" ? `btn-${theme}` : ""}${className}`;
|
||||
}
|
||||
|
||||
export let tooltip: string | undefined = undefined;
|
||||
export let active = false;
|
||||
|
@ -48,11 +53,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<button
|
||||
bind:this={buttonRef}
|
||||
{id}
|
||||
class={`btn ${className}`}
|
||||
class={extendClassName(className, theme)}
|
||||
class:active
|
||||
class:dropdown-toggle={dropdownProps.dropdown}
|
||||
class:btn-day={!nightMode}
|
||||
class:btn-night={nightMode}
|
||||
class:btn-day={theme === 'anki' && !nightMode}
|
||||
class:btn-night={theme === 'anki' && nightMode}
|
||||
title={tooltip}
|
||||
{...dropdownProps}
|
||||
disabled={_disabled}
|
||||
|
|
|
@ -6,24 +6,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import type { Readable } from "svelte/store";
|
||||
import { onMount, createEventDispatcher, getContext } from "svelte";
|
||||
import { disabledKey } from "./contextKeys";
|
||||
import SelectOption from "./SelectOption.svelte";
|
||||
|
||||
interface Option {
|
||||
label: string;
|
||||
value: string;
|
||||
selected?: false;
|
||||
}
|
||||
export let id: string | undefined = undefined;
|
||||
let className = "";
|
||||
export { className as class };
|
||||
|
||||
export let id: string;
|
||||
export let className = "";
|
||||
export let tooltip: string;
|
||||
|
||||
function extendClassName(classes: string) {
|
||||
return `form-select ${classes}`;
|
||||
}
|
||||
export let tooltip: string | undefined = undefined;
|
||||
|
||||
export let disables = true;
|
||||
export let options: Option[];
|
||||
|
||||
let buttonRef: HTMLSelectElement;
|
||||
|
||||
|
@ -57,14 +47,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</style>
|
||||
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
|
||||
<select
|
||||
tabindex="-1"
|
||||
bind:this={buttonRef}
|
||||
disabled={_disabled}
|
||||
{id}
|
||||
class={extendClassName(className)}
|
||||
title={tooltip}>
|
||||
{#each options as option}
|
||||
<SelectOption {...option} />
|
||||
{/each}
|
||||
class={` ${className}`}
|
||||
title={tooltip}
|
||||
on:change>
|
||||
<slot />
|
||||
</select>
|
||||
|
|
|
@ -3,9 +3,10 @@ Copyright: Ankitects Pty Ltd and contributors
|
|||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="typescript">
|
||||
export let label: string;
|
||||
export let value: string;
|
||||
export let value: string | undefined = undefined;
|
||||
export let selected = false;
|
||||
</script>
|
||||
|
||||
<option {selected} {value}>{label}</option>
|
||||
<option {value} {selected}>
|
||||
<slot />
|
||||
</option>
|
||||
|
|
|
@ -4,6 +4,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
-->
|
||||
<script lang="typescript">
|
||||
export let id: string | undefined = undefined;
|
||||
let className = "";
|
||||
export { className as class };
|
||||
export let style: string;
|
||||
</script>
|
||||
|
||||
|
@ -13,6 +15,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</style>
|
||||
|
||||
<div {id} {style}>
|
||||
<div {id} class={className} {style}>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
@ -48,6 +48,7 @@ ts_library(
|
|||
"DeckOptionsPage",
|
||||
"lib",
|
||||
"//ts/lib",
|
||||
"//ts/components",
|
||||
"@npm//@popperjs",
|
||||
"@npm//svelte2tsx",
|
||||
],
|
||||
|
|
|
@ -5,7 +5,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<script lang="ts">
|
||||
import * as tr from "lib/i18n";
|
||||
import type { DeckOptionsState, ConfigListEntry } from "./lib";
|
||||
|
||||
import WithTheming from "components/WithTheming.svelte";
|
||||
import StickyBar from "components/StickyBar.svelte";
|
||||
import ButtonToolbar from "components/ButtonToolbar.svelte";
|
||||
import ButtonToolbarItem from "components/ButtonToolbarItem.svelte";
|
||||
import ButtonGroup from "components/ButtonGroup.svelte";
|
||||
import ButtonGroupItem from "components/ButtonGroupItem.svelte";
|
||||
|
||||
import SelectButton from "components/SelectButton.svelte";
|
||||
import SelectOption from "components/SelectOption.svelte";
|
||||
import OptionsDropdown from "./OptionsDropdown.svelte";
|
||||
|
||||
export let state: DeckOptionsState;
|
||||
|
@ -21,28 +30,30 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.selector-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 6fr 1fr;
|
||||
grid-column-gap: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<StickyBar>
|
||||
<div>{tr.actionsOptionsFor({ val: state.currentDeck.name })}</div>
|
||||
|
||||
<div class="selector-grid">
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
<select class="form-select" on:change={blur}>
|
||||
{#each $configList as entry}
|
||||
<option value={entry.idx} selected={entry.current}>
|
||||
{configLabel(entry)}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<WithTheming style="--toolbar-size: 30px; --toolbar-wrap: nowrap">
|
||||
<ButtonToolbar class="justify-content-between">
|
||||
<ButtonToolbarItem>
|
||||
<ButtonGroup class="flex-grow-1">
|
||||
<ButtonGroupItem>
|
||||
<SelectButton class="flex-grow-1" on:change={blur}>
|
||||
{#each $configList as entry}
|
||||
<SelectOption
|
||||
value={String(entry.idx)}
|
||||
selected={entry.current}>
|
||||
{configLabel(entry)}
|
||||
</SelectOption>
|
||||
{/each}
|
||||
</SelectButton>
|
||||
</ButtonGroupItem>
|
||||
</ButtonGroup>
|
||||
</ButtonToolbarItem>
|
||||
|
||||
<OptionsDropdown {state} />
|
||||
</div>
|
||||
<ButtonToolbarItem>
|
||||
<OptionsDropdown {state} />
|
||||
</ButtonToolbarItem>
|
||||
</ButtonToolbar>
|
||||
</WithTheming>
|
||||
</StickyBar>
|
||||
|
|
|
@ -7,6 +7,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import { textInputModal } from "./textInputModal";
|
||||
import type { DeckOptionsState } from "./lib";
|
||||
|
||||
import ButtonGroup from "components/ButtonGroup.svelte";
|
||||
import ButtonGroupItem from "components/ButtonGroupItem.svelte";
|
||||
|
||||
import LabelButton from "components/LabelButton.svelte";
|
||||
import DropdownMenu from "components/DropdownMenu.svelte";
|
||||
import DropdownItem from "components/DropdownItem.svelte";
|
||||
import DropdownDivider from "components/DropdownDivider.svelte";
|
||||
import WithDropdownMenu from "components/WithDropdownMenu.svelte";
|
||||
|
||||
export let state: DeckOptionsState;
|
||||
|
||||
function addConfig(): void {
|
||||
|
@ -60,38 +69,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
:global(svg) {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
</style>
|
||||
<ButtonGroup>
|
||||
<ButtonGroupItem>
|
||||
<LabelButton theme="primary" on:click={() => save(false)}>Save</LabelButton>
|
||||
</ButtonGroupItem>
|
||||
|
||||
<div class="btn-group" dir="ltr">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
on:click={() => save(false)}>Save</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<span class="visually-hidden">Toggle Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href={'#'} on:click={addConfig}>Add Config</a></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href={'#'} on:click={renameConfig}>Rename Config</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href={'#'} on:click={removeConfig}>Remove Config</a>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="dropdown-divider" />
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href={'#'} on:click={() => save(true)}>Save to All
|
||||
Children</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ButtonGroupItem>
|
||||
<WithDropdownMenu let:createDropdown let:menuId>
|
||||
<LabelButton on:mount={createDropdown} />
|
||||
<DropdownMenu id={menuId}>
|
||||
<DropdownItem on:click={addConfig}>Add Config</DropdownItem>
|
||||
<DropdownItem on:click={renameConfig}>Rename Config</DropdownItem>
|
||||
<DropdownItem on:click={removeConfig}>Remove Config</DropdownItem>
|
||||
<DropdownDivider />
|
||||
<DropdownItem on:click={() => save(true)}>
|
||||
Save to All Children
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</WithDropdownMenu>
|
||||
</ButtonGroupItem>
|
||||
</ButtonGroup>
|
||||
|
|
|
@ -10,20 +10,33 @@ import SpinBoxFloat from "./SpinBoxFloat.svelte";
|
|||
import EnumSelector from "./EnumSelector.svelte";
|
||||
import CheckBox from "./CheckBox.svelte";
|
||||
|
||||
import { nightModeKey } from "components/contextKeys";
|
||||
|
||||
export async function deckOptions(
|
||||
target: HTMLDivElement,
|
||||
deckId: number
|
||||
): Promise<DeckOptionsPage> {
|
||||
checkNightMode();
|
||||
await setupI18n({
|
||||
modules: [ModuleName.SCHEDULING, ModuleName.ACTIONS, ModuleName.DECK_CONFIG],
|
||||
});
|
||||
const info = await getDeckOptionsInfo(deckId);
|
||||
const [info] = await Promise.all([
|
||||
getDeckOptionsInfo(deckId),
|
||||
setupI18n({
|
||||
modules: [
|
||||
ModuleName.SCHEDULING,
|
||||
ModuleName.ACTIONS,
|
||||
ModuleName.DECK_CONFIG,
|
||||
],
|
||||
}),
|
||||
]);
|
||||
|
||||
const nightMode = checkNightMode();
|
||||
const context = new Map();
|
||||
context.set(nightModeKey, nightMode);
|
||||
|
||||
const state = new DeckOptionsState(deckId, info);
|
||||
return new DeckOptionsPage({
|
||||
target,
|
||||
props: { state },
|
||||
});
|
||||
context,
|
||||
} as any);
|
||||
}
|
||||
|
||||
export const deckConfigComponents = {
|
||||
|
|
|
@ -62,7 +62,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</ButtonGroupItem>
|
||||
|
||||
<ButtonGroupItem>
|
||||
<WithDropdownMenu let:menuId let:createDropdown>
|
||||
<WithDropdownMenu let:createDropdown let:menuId>
|
||||
<IconButton on:mount={createDropdown}>
|
||||
{@html functionIcon}
|
||||
</IconButton>
|
||||
|
|
|
@ -20,7 +20,7 @@ export function initToolbar(i18n: Promise<void>): Promise<EditorToolbar> {
|
|||
toolbarResolve = resolve;
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.addEventListener("DOMContentLoaded", () =>
|
||||
i18n.then(() => {
|
||||
const target = document.body;
|
||||
const anchor = document.getElementById("fields")!;
|
||||
|
@ -33,8 +33,8 @@ export function initToolbar(i18n: Promise<void>): Promise<EditorToolbar> {
|
|||
);
|
||||
|
||||
toolbarResolve(new EditorToolbar({ target, anchor, context } as any));
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return toolbarPromise;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue