update ts deps

- prettier's formatting has changed, so files needed to be reformatted
- dart is spitting out deprecation warnings like:

254 │   2: $spacer / 2,
    │      ^^^^^^^^^^^
    ╵
    bazel-out/darwin-fastbuild/bin/ts/sass/bootstrap/_variables.scss 254:6  @import
    ts/sass/button_mixins.scss 2:9                                          @use
    ts/components/ColorPicker.svelte 2:5                                    root stylesheet

DEPRECATION WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0.0.

Recommendation: math.div($grid-gutter-width, 2)
This commit is contained in:
Damien Elmes 2021-05-26 09:21:33 +10:00
parent cdc40c1ce4
commit 0026506543
69 changed files with 1429 additions and 1531 deletions

View File

@ -61,10 +61,13 @@ async function _updateQA(
onShownHook = [onshown];
const qa = document.getElementById("qa")!;
const renderError = (kind: string) => (error: Error): void => {
const renderError =
(kind: string) =>
(error: Error): void => {
const errorMessage = String(error).substring(0, 2000);
const errorStack = String(error.stack).substring(0, 2000);
qa.innerHTML = `Invalid ${kind} on card: ${errorMessage}\n${errorStack}`.replace(
qa.innerHTML =
`Invalid ${kind} on card: ${errorMessage}\n${errorStack}`.replace(
/\n/g,
"<br>"
);

View File

@ -18,6 +18,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setContext(dropdownKey, null);
</script>
<WithTheming style="--toolbar-wrap: nowrap; ">
<ButtonToolbar
{id}
class={`dropdown-menu btn-dropdown-menu ${className}`}
nowrap={true}
{api}
>
<slot />
</ButtonToolbar>
</WithTheming>
<style lang="scss">
:global(.dropdown-menu.btn-dropdown-menu) {
display: none;
@ -36,13 +47,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
display: flex;
}
</style>
<WithTheming style="--toolbar-wrap: nowrap; ">
<ButtonToolbar
{id}
class={`dropdown-menu btn-dropdown-menu ${className}`}
nowrap={true}
{api}>
<slot />
</ButtonToolbar>
</WithTheming>

View File

@ -24,12 +24,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return { detach, position };
}
const {
registerComponent,
items,
dynamicItems,
getDynamicInterface,
} = makeInterface(makeRegistration);
const { registerComponent, items, dynamicItems, getDynamicInterface } =
makeInterface(makeRegistration);
$: for (const [index, item] of $items.entries()) {
if ($items.length === 1) {
@ -49,9 +45,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let buttonGroupRef: HTMLDivElement;
$: if (api && buttonGroupRef) {
const { addComponent, updateRegistration } = getDynamicInterface(
buttonGroupRef
);
const { addComponent, updateRegistration } =
getDynamicInterface(buttonGroupRef);
const insertButton = (button: SvelteComponent, position: Identifier = 0) =>
addComponent(button, (added, parent) => insert(added, parent, position));
@ -78,20 +73,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<style lang="scss">
div {
flex-wrap: var(--toolbar-wrap);
padding: calc(var(--toolbar-size) / 10);
margin: 0;
}
</style>
<div
bind:this={buttonGroupRef}
{id}
class={`btn-group ${className}`}
dir="ltr"
role="group">
role="group"
>
<slot />
{#each $dynamicItems as item}
<ButtonGroupItem id={item[0].id} registration={item[1]}>
@ -99,3 +87,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
{/each}
</div>
<style lang="scss">
div {
flex-wrap: var(--toolbar-wrap);
padding: calc(var(--toolbar-size) / 10);
margin: 0;
}
</style>

View File

@ -44,9 +44,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
detach.subscribe((value: boolean) => (detached = value));
position.subscribe((value: ButtonPosition) => (position_ = value));
} else if (hasContext(buttonGroupKey)) {
const registerComponent = getContext<Register<ButtonRegistration>>(
buttonGroupKey
);
const registerComponent =
getContext<Register<ButtonRegistration>>(buttonGroupKey);
const { detach, position } = registerComponent();
detach.subscribe((value: boolean) => (detached = value));
position.subscribe((value: ButtonPosition) => (position_ = value));

View File

@ -24,9 +24,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return { detach };
}
const { registerComponent, dynamicItems, getDynamicInterface } = makeInterface(
makeRegistration
);
const { registerComponent, dynamicItems, getDynamicInterface } =
makeInterface(makeRegistration);
setContext(buttonToolbarKey, registerComponent);
@ -34,9 +33,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let buttonToolbarRef: HTMLDivElement;
$: if (buttonToolbarRef && api) {
const { addComponent, updateRegistration } = getDynamicInterface(
buttonToolbarRef
);
const { addComponent, updateRegistration } =
getDynamicInterface(buttonToolbarRef);
const insertGroup = (group: SvelteComponent, position: Identifier = 0) =>
addComponent(group, (added, parent) => insert(added, parent, position));
@ -68,7 +66,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{id}
class={`btn-toolbar ${className}`}
class:flex-nowrap={nowrap}
role="toolbar">
role="toolbar"
>
<slot />
{#each $dynamicItems as item}
<ButtonToolbarItem id={item[0].id} registration={item[1]}>

View File

@ -20,9 +20,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const { detach } = registration;
detach.subscribe((value: boolean) => (detached = value));
} else if (hasContext(buttonToolbarKey)) {
const registerComponent = getContext<Register<ButtonGroupRegistration>>(
buttonToolbarKey
);
const registerComponent =
getContext<Register<ButtonGroupRegistration>>(buttonToolbarKey);
const { detach } = registerComponent();
detach.subscribe((value: boolean) => (detached = value));
} else {
@ -30,15 +29,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<style lang="scss">
div {
display: contents;
}
</style>
<!-- div is necessary to preserve item position -->
<div {id}>
<Detachable {detached}>
<slot />
</Detachable>
</div>
<style lang="scss">
div {
display: contents;
}
</style>

View File

@ -25,6 +25,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => dispatch("mount", { button: buttonRef, input: inputRef }));
</script>
<button
bind:this={buttonRef}
tabindex="-1"
{id}
class={`btn ${className}`}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
on:click={delegateToInput}
on:mousedown|preventDefault
>
<input tabindex="-1" bind:this={inputRef} type="color" on:change />
</button>
<style lang="scss">
@use "ts/sass/button_mixins" as button;
@ -59,16 +73,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
opacity: 0;
}
</style>
<button
bind:this={buttonRef}
tabindex="-1"
{id}
class={`btn ${className}`}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
on:click={delegateToInput}
on:mousedown|preventDefault>
<input tabindex="-1" bind:this={inputRef} type="color" on:change />
</button>

View File

@ -20,6 +20,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => dispatch("mount", { button: buttonRef }));
</script>
<button
{id}
bind:this={buttonRef}
class={`btn dropdown-item ${className}`}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
on:click
on:mousedown|preventDefault
>
<slot />
</button>
<style lang="scss">
@use 'ts/sass/button_mixins' as button;
@ -57,15 +70,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
<button
{id}
bind:this={buttonRef}
class={`btn dropdown-item ${className}`}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
on:click
on:mousedown|preventDefault>
<slot />
</button>

View File

@ -11,13 +11,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setContext(dropdownKey, null);
</script>
<div {id} class="dropdown-menu">
<slot />
</div>
<style lang="scss">
div {
background-color: var(--frame-bg);
border-color: var(--medium-border);
}
</style>
<div {id} class="dropdown-menu">
<slot />
</div>

View File

@ -29,6 +29,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => dispatch("mount", { button: buttonRef }));
</script>
<button
bind:this={buttonRef}
{id}
class={`btn ${className}`}
class:active
class:dropdown-toggle={dropdownProps.dropdown}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
{...dropdownProps}
disabled={_disabled}
tabindex={tabbable ? 0 : -1}
on:click
on:mousedown|preventDefault
>
<span class="p-1"><slot /></span>
</button>
<style lang="scss">
@use "ts/sass/button_mixins" as button;
@ -61,20 +79,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
margin-right: 0.25rem;
}
</style>
<button
bind:this={buttonRef}
{id}
class={`btn ${className}`}
class:active
class:dropdown-toggle={dropdownProps.dropdown}
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
{...dropdownProps}
disabled={_disabled}
tabindex={tabbable ? 0 : -1}
on:click
on:mousedown|preventDefault>
<span class="p-1"><slot /></span>
</button>

View File

@ -34,6 +34,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => dispatch("mount", { button: buttonRef }));
</script>
<button
bind:this={buttonRef}
{id}
class={extendClassName(className, theme)}
class:active
class:dropdown-toggle={dropdownProps.dropdown}
class:btn-day={theme === "anki" && !nightMode}
class:btn-night={theme === "anki" && nightMode}
title={tooltip}
{...dropdownProps}
disabled={_disabled}
tabindex={tabbable ? 0 : -1}
on:click
on:mousedown|preventDefault
>
<slot />
</button>
<style lang="scss">
@use "ts/sass/button_mixins" as button;
@ -48,20 +66,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
@include button.btn-day;
@include button.btn-night;
</style>
<button
bind:this={buttonRef}
{id}
class={extendClassName(className, theme)}
class:active
class:dropdown-toggle={dropdownProps.dropdown}
class:btn-day={theme === 'anki' && !nightMode}
class:btn-night={theme === 'anki' && nightMode}
title={tooltip}
{...dropdownProps}
disabled={_disabled}
tabindex={tabbable ? 0 : -1}
on:click
on:mousedown|preventDefault>
<slot />
</button>

View File

@ -25,17 +25,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => dispatch("mount", { button: buttonRef }));
</script>
<style lang="scss">
@use "ts/sass/button_mixins" as button;
select {
height: var(--toolbar-size);
}
@include button.btn-day($with-hover: false);
@include button.btn-night($with-hover: false);
</style>
<!-- svelte-ignore a11y-no-onchange -->
<select
@ -47,6 +36,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:btn-day={!nightMode}
class:btn-night={nightMode}
title={tooltip}
on:change>
on:change
>
<slot />
</select>
<style lang="scss">
@use "ts/sass/button_mixins" as button;
select {
height: var(--toolbar-size);
}
@include button.btn-day($with-hover: false);
@include button.btn-night($with-hover: false);
</style>

View File

@ -8,6 +8,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export { className as class };
</script>
<nav {id} class={`pb-1 pt-1 ${className}`}>
<slot />
</nav>
<style lang="scss">
nav {
position: sticky;
@ -20,7 +24,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
border-bottom: 1px solid var(--medium-border);
}
</style>
<nav {id} class={`pb-1 pt-1 ${className}`}>
<slot />
</nav>

View File

@ -12,16 +12,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let button: ToolbarItem;
</script>
<style lang="scss">
label {
display: flex;
padding: 0 calc(var(--toolbar-size) / 10);
}
</style>
<!-- svelte-ignore a11y-label-has-associated-control -->
<label {id} class={className}>
<span class="me-1">{label}</span>
<svelte:component this={button.component} {...button} />
</label>
<style lang="scss">
label {
display: flex;
padding: 0 calc(var(--toolbar-size) / 10);
}
</style>

View File

@ -13,8 +13,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const stateStore = writable(stateMap);
function updateAllStateWithCallback(callback: (key: string) => boolean): void {
stateStore.update(
(map: StateMap): StateMap => {
stateStore.update((map: StateMap): StateMap => {
const newMap = new Map() as StateMap;
for (const key of map.keys()) {
@ -22,8 +21,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
return newMap;
}
);
});
}
export function updateAllState(event: Event): void {
@ -37,12 +35,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
function updateStateByKey(key: string, event: Event): void {
stateStore.update(
(map: StateMap): StateMap => {
stateStore.update((map: StateMap): StateMap => {
map.set(key, updaterMap.get(key)!(event));
return map;
}
);
});
}
</script>

View File

@ -9,12 +9,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let style: string;
</script>
<div {id} class={className} {style}>
<slot />
</div>
<style lang="scss">
div {
display: contents;
}
</style>
<div {id} class={className} {style}>
<slot />
</div>

View File

@ -23,22 +23,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
});
</script>
<style>
.congrats-outer {
display: flex;
justify-content: center;
}
.congrats-inner {
max-width: 30em;
}
.description {
border: 1px solid var(--border);
padding: 1em;
}
</style>
<div class="congrats-outer">
<div class="congrats-inner">
<h3>{congrats}</h3>
@ -74,3 +58,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{/if}
</div>
</div>
<style>
.congrats-outer {
display: flex;
justify-content: center;
}
.congrats-inner {
max-width: 30em;
}
.description {
border: 1px solid var(--border);
padding: 1em;
}
</style>

View File

@ -21,7 +21,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
min={1}
max={365 * 100}
defaultValue={defaults.maximumReviewInterval}
bind:value={$config.maximumReviewInterval} />
bind:value={$config.maximumReviewInterval}
/>
<SpinBoxFloat
label={tr.schedulingStartingEase()}
@ -30,7 +31,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={5}
defaultValue={defaults.initialEase}
value={$config.initialEase}
on:changed={(evt) => ($config.initialEase = evt.detail.value)} />
on:changed={(evt) => ($config.initialEase = evt.detail.value)}
/>
<SpinBoxFloat
label={tr.schedulingEasyBonus()}
@ -39,7 +41,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={3}
defaultValue={defaults.easyMultiplier}
value={$config.easyMultiplier}
on:changed={(evt) => ($config.easyMultiplier = evt.detail.value)} />
on:changed={(evt) => ($config.easyMultiplier = evt.detail.value)}
/>
<SpinBoxFloat
label={tr.schedulingIntervalModifier()}
@ -48,7 +51,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={2}
defaultValue={defaults.intervalMultiplier}
value={$config.intervalMultiplier}
on:changed={(evt) => ($config.intervalMultiplier = evt.detail.value)} />
on:changed={(evt) => ($config.intervalMultiplier = evt.detail.value)}
/>
<SpinBoxFloat
label={tr.schedulingHardInterval()}
@ -57,7 +61,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={1.3}
defaultValue={defaults.hardMultiplier}
value={$config.hardMultiplier}
on:changed={(evt) => ($config.hardMultiplier = evt.detail.value)} />
on:changed={(evt) => ($config.hardMultiplier = evt.detail.value)}
/>
<SpinBoxFloat
label={tr.schedulingNewInterval()}
@ -66,4 +71,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={1}
defaultValue={defaults.lapseMultiplier}
value={$config.lapseMultiplier}
on:changed={(evt) => ($config.lapseMultiplier = evt.detail.value)} />
on:changed={(evt) => ($config.lapseMultiplier = evt.detail.value)}
/>

View File

@ -18,10 +18,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
label={tr.deckConfigBuryNewSiblings()}
tooltip={tr.deckConfigBuryTooltip()}
defaultValue={defaults.buryNew}
bind:value={$config.buryNew} />
bind:value={$config.buryNew}
/>
<CheckBox
label={tr.deckConfigBuryReviewSiblings()}
tooltip={tr.deckConfigBuryTooltip()}
defaultValue={defaults.buryReviews}
bind:value={$config.buryReviews} />
bind:value={$config.buryReviews}
/>

View File

@ -12,12 +12,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let id: string | undefined = undefined;
</script>
<style lang="scss">
.checkbox-outer {
margin-top: 0.5em;
}
</style>
<ConfigEntry {id} label="" wholeLine={true} bind:value {defaultValue}>
<div class="checkbox-outer">
<label> <input type="checkbox" bind:checked={value} /> {label} </label>
@ -26,3 +20,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{/if}
</div>
</ConfigEntry>
<style lang="scss">
.checkbox-outer {
margin-top: 0.5em;
}
</style>

View File

@ -16,6 +16,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let state: DeckOptionsState;
</script>
<div class="outer">
<DailyLimits {state} />
<NewOptions {state} />
<LapseOptions {state} />
<BuryOptions {state} />
{#if state.v3Scheduler}
<DisplayOrder {state} />
{/if}
<GeneralOptions {state} />
<Addons {state} />
<AdvancedOptions {state} />
</div>
<style lang="scss">
:global(h2) {
margin-top: 1em;
@ -33,16 +46,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
padding-left: 16px;
}
</style>
<div class="outer">
<DailyLimits {state} />
<NewOptions {state} />
<LapseOptions {state} />
<BuryOptions {state} />
{#if state.v3Scheduler}
<DisplayOrder {state} />
{/if}
<GeneralOptions {state} />
<Addons {state} />
<AdvancedOptions {state} />
</div>

View File

@ -21,6 +21,32 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: renderedTooltip = marked(tooltip);
</script>
<div {id} class="outer">
{#if label}
<div class="table">
<span class="vcenter">
{label}
{#if renderedTooltip}
<HelpPopup html={renderedTooltip} />
{/if}
</span>
</div>
{/if}
<div class="input-grid" class:full-grid-width={wholeLine}>
<slot />
<RevertButton bind:value {defaultValue} on:revert />
</div>
<div class="full-grid-width">
{#each warnings as warning}
{#if warning}
<div class="alert alert-warning" in:slide out:slide>{warning}</div>
{/if}
{/each}
</div>
</div>
<style lang="scss">
.outer {
display: grid;
@ -52,29 +78,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
grid-template-columns: 10fr 16px;
}
</style>
<div {id} class="outer">
{#if label}
<div class="table">
<span class="vcenter">
{label}
{#if renderedTooltip}
<HelpPopup html={renderedTooltip} />
{/if}
</span>
</div>
{/if}
<div class="input-grid" class:full-grid-width={wholeLine}>
<slot />
<RevertButton bind:value {defaultValue} on:revert />
</div>
<div class="full-grid-width">
{#each warnings as warning}
{#if warning}
<div class="alert alert-warning" in:slide out:slide>{warning}</div>
{/if}
{/each}
</div>
</div>

View File

@ -64,13 +64,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
title="Add Config"
prompt="Name"
onOk={onAddConfig}
bind:modalKey={addModalKey} />
bind:modalKey={addModalKey}
/>
<TextInputModal
title="Rename Config"
prompt="Name"
onOk={onRenameConfig}
value={oldName}
bind:modalKey={renameModalKey} />
bind:modalKey={renameModalKey}
/>
<StickyBar>
<WithTheming style="--toolbar-size: 2.3rem; --toolbar-wrap: nowrap">
@ -82,7 +84,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{#each $configList as entry}
<SelectOption
value={String(entry.idx)}
selected={entry.current}>
selected={entry.current}
>
{configLabel(entry)}
</SelectOption>
{/each}

View File

@ -41,7 +41,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
min={0}
warnings={[newCardsGreaterThanParent]}
defaultValue={defaults.newPerDay}
bind:value={$config.newPerDay} />
bind:value={$config.newPerDay}
/>
<SpinBox
label={tr.schedulingMaximumReviewsday()}
@ -49,4 +50,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
min={0}
warnings={[reviewsTooLow]}
defaultValue={defaults.reviewsPerDay}
bind:value={$config.reviewsPerDay} />
bind:value={$config.reviewsPerDay}
/>

View File

@ -37,32 +37,37 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={tr.deckConfigNewGatherPriorityTooltip()}
choices={newGatherPriorityChoices}
defaultValue={defaults.newCardGatherPriority}
bind:value={$config.newCardGatherPriority} />
bind:value={$config.newCardGatherPriority}
/>
<EnumSelector
label={tr.deckConfigNewCardSortOrder()}
tooltip={tr.deckConfigNewCardSortOrderTooltip()}
choices={newSortOrderChoices}
defaultValue={defaults.newCardSortOrder}
bind:value={$config.newCardSortOrder} />
bind:value={$config.newCardSortOrder}
/>
<EnumSelector
label={tr.deckConfigNewReviewPriority()}
tooltip={tr.deckConfigNewReviewPriorityTooltip()}
choices={reviewMixChoices()}
defaultValue={defaults.newMix}
bind:value={$config.newMix} />
bind:value={$config.newMix}
/>
<EnumSelector
label={tr.deckConfigInterdayStepPriority()}
tooltip={tr.deckConfigInterdayStepPriorityTooltip()}
choices={reviewMixChoices()}
defaultValue={defaults.interdayLearningMix}
bind:value={$config.interdayLearningMix} />
bind:value={$config.interdayLearningMix}
/>
<EnumSelector
label={tr.deckConfigReviewSortOrder()}
tooltip={tr.deckConfigReviewSortOrderTooltip()}
choices={reviewOrderChoices}
defaultValue={defaults.reviewOrder}
bind:value={$config.reviewOrder} />
bind:value={$config.reviewOrder}
/>

View File

@ -21,24 +21,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
min={30}
max={600}
defaultValue={defaults.capAnswerTimeToSecs}
bind:value={$config.capAnswerTimeToSecs} />
bind:value={$config.capAnswerTimeToSecs}
/>
<CheckBox
id="showAnswerTimer"
label={tr.schedulingShowAnswerTimer()}
tooltip={tr.deckConfigShowAnswerTimerTooltip()}
defaultValue={defaults.showTimer}
bind:value={$config.showTimer} />
bind:value={$config.showTimer}
/>
<h2>{tr.deckConfigAudioTitle()}</h2>
<CheckBox
label={tr.deckConfigDisableAutoplay()}
defaultValue={defaults.disableAutoplay}
bind:value={$config.disableAutoplay} />
bind:value={$config.disableAutoplay}
/>
<CheckBox
label={tr.schedulingAlwaysIncludeQuestionSideWhenReplaying()}
tooltip={tr.deckConfigAlwaysIncludeQuestionAudioTooltip()}
defaultValue={defaults.skipQuestionWhenReplayingAnswer}
bind:value={$config.skipQuestionWhenReplayingAnswer} />
bind:value={$config.skipQuestionWhenReplayingAnswer}
/>

View File

@ -20,13 +20,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
});
</script>
<span bind:this={ref} title={html}>
{@html infoCircle}
</span>
<style>
span :global(svg) {
vertical-align: text-bottom;
opacity: 0.3;
}
</style>
<span bind:this={ref} title={html}>
{@html infoCircle}
</span>

View File

@ -35,7 +35,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={tr.deckConfigRelearningStepsTooltip()}
defaultValue={defaults.relearnSteps}
value={$config.relearnSteps}
on:changed={(evt) => ($config.relearnSteps = evt.detail.value)} />
on:changed={(evt) => ($config.relearnSteps = evt.detail.value)}
/>
<SpinBox
label={tr.schedulingMinimumInterval()}
@ -43,19 +44,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
warnings={[stepsExceedMinimumInterval]}
min={1}
defaultValue={defaults.minimumLapseInterval}
bind:value={$config.minimumLapseInterval} />
bind:value={$config.minimumLapseInterval}
/>
<SpinBox
label={tr.schedulingLeechThreshold()}
tooltip={tr.deckConfigLeechThresholdTooltip()}
min={1}
defaultValue={defaults.leechThreshold}
bind:value={$config.leechThreshold} />
bind:value={$config.leechThreshold}
/>
<EnumSelector
label={tr.schedulingLeechAction()}
tooltip={tr.deckConfigLeechActionTooltip()}
choices={leechChoices}
defaultValue={defaults.leechAction}
bind:value={$config.leechAction} />
bind:value={$config.leechAction}
/>
</div>

View File

@ -42,25 +42,29 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip={tr.deckConfigLearningStepsTooltip()}
defaultValue={defaults.learnSteps}
value={$config.learnSteps}
on:changed={(evt) => ($config.learnSteps = evt.detail.value)} />
on:changed={(evt) => ($config.learnSteps = evt.detail.value)}
/>
<SpinBox
label={tr.schedulingGraduatingInterval()}
tooltip={tr.deckConfigGraduatingIntervalTooltip()}
warnings={[stepsExceedGraduatingInterval]}
defaultValue={defaults.graduatingIntervalGood}
bind:value={$config.graduatingIntervalGood} />
bind:value={$config.graduatingIntervalGood}
/>
<SpinBox
label={tr.schedulingEasyInterval()}
tooltip={tr.deckConfigEasyIntervalTooltip()}
warnings={[goodExceedsEasy]}
defaultValue={defaults.graduatingIntervalEasy}
bind:value={$config.graduatingIntervalEasy} />
bind:value={$config.graduatingIntervalEasy}
/>
<EnumSelector
label={tr.deckConfigNewInsertionOrder()}
tooltip={tr.deckConfigNewInsertionOrderTooltip()}
choices={newInsertOrderChoices}
defaultValue={defaults.newCardInsertOrder}
bind:value={$config.newCardInsertOrder} />
bind:value={$config.newCardInsertOrder}
/>

View File

@ -48,6 +48,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
{#if modified}
<div
class="img-div"
on:click={revert}
bind:this={ref}
title={tr.deckConfigRevertButtonTooltip()}
>
{@html revertIcon}
</div>
{/if}
<style lang="scss">
.img-div {
display: flex;
@ -58,13 +69,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
{#if modified}
<div
class="img-div"
on:click={revert}
bind:this={ref}
title={tr.deckConfigRevertButtonTooltip()}>
{@html revertIcon}
</div>
{/if}

View File

@ -56,8 +56,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<WithDropdownMenu let:createDropdown let:activateDropdown let:menuId>
<LabelButton on:mount={createDropdown} on:click={activateDropdown} />
<DropdownMenu id={menuId}>
<DropdownItem on:click={() => dispatch('add')}>Add Config</DropdownItem>
<DropdownItem on:click={() => dispatch('rename')}>
<DropdownItem on:click={() => dispatch("add")}>Add Config</DropdownItem>
<DropdownItem on:click={() => dispatch("rename")}>
Rename Config
</DropdownItem>
<DropdownItem on:click={removeConfig}>Remove Config</DropdownItem>

View File

@ -29,5 +29,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{max}
bind:value
class="form-control"
on:blur={checkMinMax} />
on:blur={checkMinMax}
/>
</ConfigEntry>

View File

@ -38,5 +38,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
step="0.01"
value={stringValue}
on:blur={update}
class="form-control" />
class="form-control"
/>
</ConfigEntry>

View File

@ -36,6 +36,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{defaultValue}
{warnings}
wholeLine={value.length > 2}
on:revert={revert}>
on:revert={revert}
>
<input type="text" value={stringValue} on:blur={update} class="form-control" />
</ConfigEntry>

View File

@ -47,6 +47,53 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const nightMode = getContext<boolean>(nightModeKey);
</script>
<div
bind:this={modalRef}
class="modal fade"
tabindex="-1"
aria-labelledby="modalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content" class:default-colors={nightMode}>
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">{title}</h5>
<button
type="button"
class="btn-close"
class:invert={nightMode}
data-bs-dismiss="modal"
aria-label="Close"
/>
</div>
<div class="modal-body">
<form on:submit|preventDefault={onOkClicked}>
<div class="mb-3">
<label for="prompt-input" class="col-form-label"
>{prompt}:</label
>
<input
id="prompt-input"
bind:this={inputRef}
type="text"
class="form-control"
bind:value
/>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"
>Cancel</button
>
<button type="button" class="btn btn-primary" on:click={onOkClicked}
>OK</button
>
</div>
</div>
</div>
</div>
<style lang="scss">
.default-colors {
background-color: var(--window-bg);
@ -57,49 +104,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
filter: invert(1) grayscale(100%) brightness(200%);
}
</style>
<div
bind:this={modalRef}
class="modal fade"
tabindex="-1"
aria-labelledby="modalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content" class:default-colors={nightMode}>
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">{title}</h5>
<button
type="button"
class="btn-close"
class:invert={nightMode}
data-bs-dismiss="modal"
aria-label="Close" />
</div>
<div class="modal-body">
<form on:submit|preventDefault={onOkClicked}>
<div class="mb-3">
<label
for="prompt-input"
class="col-form-label">{prompt}:</label>
<input
id="prompt-input"
bind:this={inputRef}
type="text"
class="form-control"
bind:value />
</div>
</form>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal">Cancel</button>
<button
type="button"
class="btn btn-primary"
on:click={onOkClicked}>OK</button>
</div>
</div>
</div>
</div>

View File

@ -33,8 +33,7 @@ const exampleData = {
leechAction: "LEECH_ACTION_TAG_ONLY",
leechThreshold: 8,
capAnswerTimeToSecs: 60,
other:
"eyJuZXciOnsic2VwYXJhdGUiOnRydWV9LCJyZXYiOnsiZnV6eiI6MC4wNSwibWluU3BhY2UiOjF9fQ==",
other: "eyJuZXciOnsic2VwYXJhdGUiOnRydWV9LCJyZXYiOnsiZnV6eiI6MC4wNSwibWluU3BhY2UiOjF9fQ==",
},
},
useCount: 1,

View File

@ -71,7 +71,8 @@ export class DeckOptionsState {
constructor(targetDeckId: number, data: pb.BackendProto.DeckConfigsForUpdate) {
this.targetDeckId = targetDeckId;
this.currentDeck = data.currentDeck as pb.BackendProto.DeckConfigsForUpdate.CurrentDeck;
this.currentDeck =
data.currentDeck as pb.BackendProto.DeckConfigsForUpdate.CurrentDeck;
this.defaults = data.defaults!.config! as ConfigInner;
this.configs = data.allConfig.map((config) => {
const configInner = config.config as pb.BackendProto.DeckConfig;

View File

@ -41,11 +41,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<WithShortcut shortcut={'Control+Alt?+Shift+C'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+Alt?+Shift+C"} let:createShortcut let:shortcutLabel>
<IconButton
tooltip={`${tr.editingClozeDeletion()} (${shortcutLabel})`}
on:click={onCloze}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html bracketsIcon}
</IconButton>
</WithShortcut>

View File

@ -36,23 +36,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}>
<ButtonGroupItem>
<WithShortcut shortcut={'F7'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"F7"} let:createShortcut let:shortcutLabel>
<IconButton
class="forecolor"
tooltip={appendInParentheses(tr.editingSetForegroundColor(), shortcutLabel)}
tooltip={appendInParentheses(
tr.editingSetForegroundColor(),
shortcutLabel
)}
on:click={wrapWithForecolor}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html squareFillIcon}
</IconButton>
</WithShortcut>
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'F8'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"F8"} let:createShortcut let:shortcutLabel>
<ColorPicker
tooltip={appendInParentheses(tr.editingChangeColor(), shortcutLabel)}
on:change={setWithCurrentColor}
on:mount={createShortcut} />
on:mount={createShortcut}
/>
</WithShortcut>
</ButtonGroupItem>
</ButtonGroup>

View File

@ -48,16 +48,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="insertUnorderedList"
update={() => document.queryCommandState('insertUnorderedList')}
update={() => document.queryCommandState("insertUnorderedList")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingUnorderedList()}
{active}
on:click={(event) => {
document.execCommand('insertUnorderedList');
document.execCommand("insertUnorderedList");
updateState(event);
}}>
}}
>
{@html ulIcon}
</IconButton>
</WithState>
@ -66,16 +68,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="insertOrderedList"
update={() => document.queryCommandState('insertOrderedList')}
update={() => document.queryCommandState("insertOrderedList")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingOrderedList()}
{active}
on:click={(event) => {
document.execCommand('insertOrderedList');
document.execCommand("insertOrderedList");
updateState(event);
}}>
}}
>
{@html olIcon}
</IconButton>
</WithState>
@ -93,16 +97,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="justifyLeft"
update={() => document.queryCommandState('justifyLeft')}
update={() => document.queryCommandState("justifyLeft")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingAlignLeft()}
{active}
on:click={(event) => {
document.execCommand('justifyLeft');
document.execCommand("justifyLeft");
updateState(event);
}}>
}}
>
{@html justifyLeftIcon}
</IconButton>
</WithState>
@ -111,16 +117,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="justifyCenter"
update={() => document.queryCommandState('justifyCenter')}
update={() =>
document.queryCommandState("justifyCenter")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingCenter()}
{active}
on:click={(event) => {
document.execCommand('justifyCenter');
document.execCommand("justifyCenter");
updateState(event);
}}>
}}
>
{@html justifyCenterIcon}
</IconButton>
</WithState>
@ -129,16 +138,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="justifyRight"
update={() => document.queryCommandState('justifyRight')}
update={() =>
document.queryCommandState("justifyRight")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingAlignRight()}
{active}
on:click={(event) => {
document.execCommand('justifyRight');
document.execCommand("justifyRight");
updateState(event);
}}>
}}
>
{@html justifyRightIcon}
</IconButton>
</WithState>
@ -147,16 +159,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<WithState
key="justifyFull"
update={() => document.queryCommandState('justifyFull')}
update={() => document.queryCommandState("justifyFull")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={tr.editingJustify()}
{active}
on:click={(event) => {
document.execCommand('justifyFull');
document.execCommand("justifyFull");
updateState(event);
}}>
}}
>
{@html justifyFullIcon}
</IconButton>
</WithState>
@ -169,7 +183,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<IconButton
on:click={outdentListItem}
tooltip={tr.editingOutdent()}>
tooltip={tr.editingOutdent()}
>
{@html outdentIcon}
</IconButton>
</ButtonGroupItem>
@ -177,7 +192,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem>
<IconButton
on:click={indentListItem}
tooltip={tr.editingIndent()}>
tooltip={tr.editingIndent()}
>
{@html indentIcon}
</IconButton>
</ButtonGroupItem>

View File

@ -26,20 +26,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+B'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+B"} let:createShortcut let:shortcutLabel>
<WithState
key="bold"
update={() => document.queryCommandState('bold')}
update={() => document.queryCommandState("bold")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={appendInParentheses(tr.editingBoldText(), shortcutLabel)}
{active}
on:click={(event) => {
document.execCommand('bold');
document.execCommand("bold");
updateState(event);
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html boldIcon}
</IconButton>
</WithState>
@ -47,20 +49,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+I'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+I"} let:createShortcut let:shortcutLabel>
<WithState
key="italic"
update={() => document.queryCommandState('italic')}
update={() => document.queryCommandState("italic")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={appendInParentheses(tr.editingItalicText(), shortcutLabel)}
{active}
on:click={(event) => {
document.execCommand('italic');
document.execCommand("italic");
updateState(event);
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html italicIcon}
</IconButton>
</WithState>
@ -68,20 +72,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+U'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+U"} let:createShortcut let:shortcutLabel>
<WithState
key="underline"
update={() => document.queryCommandState('underline')}
update={() => document.queryCommandState("underline")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={appendInParentheses(tr.editingUnderlineText(), shortcutLabel)}
tooltip={appendInParentheses(
tr.editingUnderlineText(),
shortcutLabel
)}
{active}
on:click={(event) => {
document.execCommand('underline');
document.execCommand("underline");
updateState(event);
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html underlineIcon}
</IconButton>
</WithState>
@ -89,20 +98,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+='} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+="} let:createShortcut let:shortcutLabel>
<WithState
key="superscript"
update={() => document.queryCommandState('superscript')}
update={() => document.queryCommandState("superscript")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={appendInParentheses(tr.editingSuperscript(), shortcutLabel)}
tooltip={appendInParentheses(
tr.editingSuperscript(),
shortcutLabel
)}
{active}
on:click={(event) => {
document.execCommand('superscript');
document.execCommand("superscript");
updateState(event);
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html superscriptIcon}
</IconButton>
</WithState>
@ -110,20 +124,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+Shift+='} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+Shift+="} let:createShortcut let:shortcutLabel>
<WithState
key="subscript"
update={() => document.queryCommandState('subscript')}
update={() => document.queryCommandState("subscript")}
let:state={active}
let:updateState>
let:updateState
>
<IconButton
tooltip={appendInParentheses(tr.editingSubscript(), shortcutLabel)}
{active}
on:click={(event) => {
document.execCommand('subscript');
document.execCommand("subscript");
updateState(event);
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html subscriptIcon}
</IconButton>
</WithState>
@ -131,13 +147,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+R'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+R"} let:createShortcut let:shortcutLabel>
<IconButton
tooltip={appendInParentheses(tr.editingRemoveFormatting(), shortcutLabel)}
tooltip={appendInParentheses(
tr.editingRemoveFormatting(),
shortcutLabel
)}
on:click={() => {
document.execCommand('removeFormat');
document.execCommand("removeFormat");
}}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html eraserIcon}
</IconButton>
</WithShortcut>

View File

@ -19,18 +19,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<LabelButton
disables={false}
tooltip={tr.editingCustomizeFields()}
on:click={() => bridgeCommand('fields')}>
on:click={() => bridgeCommand("fields")}
>
{tr.editingFields()}...
</LabelButton>
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+L'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+L"} let:createShortcut let:shortcutLabel>
<LabelButton
disables={false}
tooltip={`${tr.editingCustomizeCardTemplates()} (${shortcutLabel})`}
on:click={() => bridgeCommand('cards')}
on:mount={createShortcut}>
on:click={() => bridgeCommand("cards")}
on:mount={createShortcut}
>
{tr.editingCards()}...
</LabelButton>
</WithShortcut>

View File

@ -10,12 +10,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import LabelButton from "components/LabelButton.svelte";
</script>
<WithShortcut shortcut={'Control+Shift+P'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+Shift+P"} let:createShortcut let:shortcutLabel>
<LabelButton
tooltip={tr.browsingPreviewSelectedCard({ val: shortcutLabel })}
disables={false}
on:click={() => bridgeCommand('preview')}
on:mount={createShortcut}>
on:click={() => bridgeCommand("preview")}
on:mount={createShortcut}
>
{tr.actionsPreview()}
</LabelButton>
</WithShortcut>

View File

@ -36,22 +36,27 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}>
<ButtonGroupItem>
<WithShortcut shortcut={'F3'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"F3"} let:createShortcut let:shortcutLabel>
<IconButton
tooltip={appendInParentheses(tr.editingAttachPicturesaudiovideo(), shortcutLabel)}
tooltip={appendInParentheses(
tr.editingAttachPicturesaudiovideo(),
shortcutLabel
)}
on:click={onAttachment}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html paperclipIcon}
</IconButton>
</WithShortcut>
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'F5'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"F5"} let:createShortcut let:shortcutLabel>
<IconButton
tooltip={appendInParentheses(tr.editingRecordAudio(), shortcutLabel)}
on:click={onRecord}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html micIcon}
</IconButton>
</WithShortcut>
@ -69,72 +74,84 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<DropdownMenu id={menuId}>
<WithShortcut
shortcut={'Control+M, M'}
shortcut={"Control+M, M"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('\\(', '\\)')}
on:mount={createShortcut}>
on:click={() => wrap("\\(", "\\)")}
on:mount={createShortcut}
>
{tr.editingMathjaxInline()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
</WithShortcut>
<WithShortcut
shortcut={'Control+M, E'}
shortcut={"Control+M, E"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('\\[', '\\]')}
on:mount={createShortcut}>
on:click={() => wrap("\\[", "\\]")}
on:mount={createShortcut}
>
{tr.editingMathjaxBlock()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
</WithShortcut>
<WithShortcut
shortcut={'Control+M, C'}
shortcut={"Control+M, C"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('\\(\\ce{', '}\\)')}
on:mount={createShortcut}>
on:click={() => wrap("\\(\\ce{", "}\\)")}
on:mount={createShortcut}
>
{tr.editingMathjaxChemistry()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
</WithShortcut>
<WithShortcut
shortcut={'Control+T, T'}
shortcut={"Control+T, T"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('[latex]', '[/latex]')}
on:mount={createShortcut}>
on:click={() => wrap("[latex]", "[/latex]")}
on:mount={createShortcut}
>
{tr.editingLatex()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
</WithShortcut>
<WithShortcut
shortcut={'Control+T, E'}
shortcut={"Control+T, E"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('[$]', '[/$]')}
on:mount={createShortcut}>
on:click={() => wrap("[$]", "[/$]")}
on:mount={createShortcut}
>
{tr.editingLatexEquation()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
</WithShortcut>
<WithShortcut
shortcut={'Control+T, M'}
shortcut={"Control+T, M"}
let:createShortcut
let:shortcutLabel>
let:shortcutLabel
>
<DropdownItem
on:click={() => wrap('[$$]', '[/$$]')}
on:mount={createShortcut}>
on:click={() => wrap("[$$]", "[/$$]")}
on:mount={createShortcut}
>
{tr.editingLatexMathEnv()}
<span class="ps-1 float-end">{shortcutLabel}</span>
</DropdownItem>
@ -144,11 +161,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem>
<ButtonGroupItem>
<WithShortcut shortcut={'Control+Shift+X'} let:createShortcut let:shortcutLabel>
<WithShortcut shortcut={"Control+Shift+X"} let:createShortcut let:shortcutLabel>
<IconButton
tooltip={appendInParentheses(tr.editingHtmlEditor(), shortcutLabel)}
on:click={onHtmlEdit}
on:mount={createShortcut}>
on:mount={createShortcut}
>
{@html xmlIcon}
</IconButton>
</WithShortcut>

View File

@ -78,9 +78,9 @@ export function caretToEnd(currentField: EditingArea): void {
selection.addRange(range);
}
const getAnchorParent = <T extends Element>(
predicate: (element: Element) => element is T
) => (currentField: DocumentOrShadowRoot): T | null => {
const getAnchorParent =
<T extends Element>(predicate: (element: Element) => element is T) =>
(currentField: DocumentOrShadowRoot): T | null => {
const anchor = currentField.getSelection()?.anchorNode;
if (!anchor) {
@ -96,7 +96,7 @@ const getAnchorParent = <T extends Element>(
}
return anchorParent;
};
};
const isListItem = (element: Element): element is HTMLLIElement =>
window.getComputedStyle(element).display === "list-item";

View File

@ -8,12 +8,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let bounds: GraphBounds;
</script>
<g class="x-ticks" transform={`translate(0, ${bounds.height - bounds.marginBottom})`} />
<g class="y-ticks" transform={`translate(${bounds.marginLeft}, 0)`} />
<g class="y2-ticks" transform={`translate(${bounds.width - bounds.marginRight}, 0)`} />
<style lang="scss">
g :global(.domain) {
opacity: 0.05;
}
</style>
<g class="x-ticks" transform={`translate(0, ${bounds.height - bounds.marginBottom})`} />
<g class="y-ticks" transform={`translate(${bounds.marginLeft}, 0)`} />
<g class="y2-ticks" transform={`translate(${bounds.width - bounds.marginRight}, 0)`} />

View File

@ -28,8 +28,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
bounds.width = 225;
bounds.marginBottom = 0;
let graphData = (null as unknown) as GraphData;
let tableData = (null as unknown) as TableDatum[];
let graphData = null as unknown as GraphData;
let tableData = null as unknown as TableDatum[];
$: {
graphData = gatherData(sourceData, $cardCountsSeparateInactive);
@ -40,6 +40,52 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const total = tr2.statisticsCountsTotalCards();
</script>
<Graph title={graphData.title}>
<InputBox>
<label>
<input type="checkbox" bind:checked={$cardCountsSeparateInactive} />
{label}
</label>
</InputBox>
<div class="counts-outer">
<svg
bind:this={svg}
viewBox={`0 0 ${bounds.width} ${bounds.height}`}
width={bounds.width}
height={bounds.height}
style="opacity: {graphData.totalCards ? 1 : 0}"
>
<g class="counts" />
</svg>
<div class="counts-table">
<table>
{#each tableData as d, _idx}
<tr>
<!-- prettier-ignore -->
<td>
<span style="color: {d.colour};">&nbsp;</span>
{#if browserLinksSupported}
<span class="search-link" on:click={() => dispatch('search', { query: d.query })}>{d.label}</span>
{:else}
<span>{d.label}</span>
{/if}
</td>
<td class="right">{d.count}</td>
<td class="right">{d.percent}</td>
</tr>
{/each}
<tr>
<td><span style="visibility: hidden;"></span> {total}</td>
<td class="right">{graphData.totalCards}</td>
<td />
</tr>
</table>
</div>
</div>
</Graph>
<style lang="scss">
svg {
transition: opacity 1s;
@ -74,48 +120,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
text-decoration: underline;
}
</style>
<Graph title={graphData.title}>
<InputBox>
<label>
<input type="checkbox" bind:checked={$cardCountsSeparateInactive} />
{label}
</label>
</InputBox>
<div class="counts-outer">
<svg
bind:this={svg}
viewBox={`0 0 ${bounds.width} ${bounds.height}`}
width={bounds.width}
height={bounds.height}
style="opacity: {graphData.totalCards ? 1 : 0}">
<g class="counts" />
</svg>
<div class="counts-table">
<table>
{#each tableData as d, _idx}
<tr>
<!-- prettier-ignore -->
<td>
<span style="color: {d.colour};">&nbsp;</span>
{#if browserLinksSupported}
<span class="search-link" on:click={() => dispatch('search', { query: d.query })}>{d.label}</span>
{:else}
<span>{d.label}</span>
{/if}
</td>
<td class="right">{d.count}</td>
<td class="right">{d.percent}</td>
</tr>
{/each}
<tr>
<td><span style="visibility: hidden;"></span> {total}</td>
<td class="right">{graphData.totalCards}</td>
<td />
</tr>
</table>
</div>
</div>
</Graph>

View File

@ -1,3 +1,5 @@
<path class="cumulative-overlay" />
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
@ -25,5 +27,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
stroke-opacity: var(--area-stroke-opacity);
}
</style>
<path class="cumulative-overlay" />

View File

@ -7,6 +7,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let subtitle: string | null = null;
</script>
<div class="graph" tabindex="-1">
<h1>{title}</h1>
{#if subtitle}
<div class="subtitle">{subtitle}</div>
{/if}
<slot />
</div>
<style lang="scss">
.graph {
margin-left: auto;
@ -65,13 +75,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
margin-bottom: 1em;
}
</style>
<div class="graph" tabindex="-1">
<h1>{title}</h1>
{#if subtitle}
<div class="subtitle">{subtitle}</div>
{/if}
<slot />
</div>

View File

@ -25,14 +25,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<style lang="scss">
div {
@media only screen and (max-width: 600px) {
font-size: 12px;
}
}
</style>
<div>
<WithGraphData
{search}
@ -40,7 +32,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let:loading
let:sourceData
let:preferences
let:revlogRange>
let:revlogRange
>
{#if controller}
<svelte:component this={controller} {search} {days} {loading} />
{/if}
@ -53,8 +46,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{preferences}
{revlogRange}
{nightMode}
on:search={browserSearch} />
on:search={browserSearch}
/>
{/each}
{/if}
</WithGraphData>
</div>
<style lang="scss">
div {
@media only screen and (max-width: 600px) {
font-size: 12px;
}
}
</style>

View File

@ -1,3 +1,5 @@
<g class="hover-columns" />
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
@ -15,5 +17,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
<g class="hover-columns" />

View File

@ -1,3 +1,7 @@
<div>
<slot />
</div>
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
@ -17,7 +21,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
<div>
<slot />
</div>

View File

@ -9,6 +9,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const noData = tr.statisticsNoData();
</script>
<g class="no-data">
<rect x="0" y="0" width={bounds.width} height={bounds.height} />
<text x="{bounds.width / 2}," y={bounds.height / 2}>{noData}</text>
</g>
<style lang="scss">
.no-data {
rect {
@ -21,8 +26,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
<g class="no-data">
<rect x="0" y="0" width={bounds.width} height={bounds.height} />
<text x="{bounds.width / 2}," y={bounds.height / 2}>{noData}</text>
</g>

View File

@ -67,6 +67,48 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const all = tr.statisticsRangeAllHistory();
</script>
<div class="range-box">
<div class="spin" class:loading></div>
<InputBox>
<label>
<input type="radio" bind:group={searchRange} value={SearchRange.Deck} />
{deck}
</label>
<label>
<input
type="radio"
bind:group={searchRange}
value={SearchRange.Collection}
/>
{collection}
</label>
<input
type="text"
bind:value={displayedSearch}
on:keyup={searchKeyUp}
on:focus={() => {
searchRange = SearchRange.Custom;
}}
placeholder={searchLabel}
/>
</InputBox>
<InputBox>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.Year} />
{year}
</label>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.All} />
{all}
</label>
</InputBox>
</div>
<div class="range-box-pad" />
<style lang="scss">
.range-box {
position: fixed;
@ -111,43 +153,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
height: 2em;
}
</style>
<div class="range-box">
<div class="spin" class:loading></div>
<InputBox>
<label>
<input type="radio" bind:group={searchRange} value={SearchRange.Deck} />
{deck}
</label>
<label>
<input
type="radio"
bind:group={searchRange}
value={SearchRange.Collection} />
{collection}
</label>
<input
type="text"
bind:value={displayedSearch}
on:keyup={searchKeyUp}
on:focus={() => {
searchRange = SearchRange.Custom;
}}
placeholder={searchLabel} />
</InputBox>
<InputBox>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.Year} />
{year}
</label>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.All} />
{all}
</label>
</InputBox>
</div>
<div class="range-box-pad" />

View File

@ -8,6 +8,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let tableData: TableDatum[];
</script>
<div>
<table dir={i18n.direction()}>
{#each tableData as { label, value }}
<tr>
<td class="align-end">{label}:</td>
<td class="align-start">{value}</td>
</tr>
{/each}
</table>
</div>
<style lang="scss">
div {
display: flex;
@ -22,14 +33,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
text-align: start;
}
</style>
<div>
<table dir={i18n.direction()}>
{#each tableData as { label, value }}
<tr>
<td class="align-end">{label}:</td>
<td class="align-start">{value}</td>
</tr>
{/each}
</table>
</div>

View File

@ -18,12 +18,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<style lang="scss">
.legend {
text-align: center;
}
</style>
{#if todayData}
<Graph title={todayData.title}>
<div class="legend">
@ -33,3 +27,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</div>
</Graph>
{/if}
<style lang="scss">
.legend {
text-align: center;
}
</style>

View File

@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let y: number = 0;
export let show = true;
let container = (null as unknown) as HTMLDivElement;
let container = null as unknown as HTMLDivElement;
let adjustedX: number, adjustedY: number;
@ -24,6 +24,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
</script>
<div
bind:this={container}
class="tooltip"
style="left: {adjustedX}px; top: {adjustedY}px; opacity: {show ? 1 : 0}"
>
{@html html}
</div>
<style lang="scss">
.tooltip {
position: absolute;
@ -41,10 +49,3 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
</style>
<div
bind:this={container}
class="tooltip"
style="left: {adjustedX}px; top: {adjustedY}px; opacity: {show ? 1 : 0}">
{@html html}
</div>

View File

@ -84,4 +84,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{revlogRange}
loading={$graphLoading || $prefsLoading}
sourceData={$graphValue}
preferences={$prefsValue} />
preferences={$prefsValue}
/>

View File

@ -158,13 +158,9 @@ export function histogramGraph(
);
}
const hoverData: [
Bin<number, number>,
number
][] = data.bins.map((bin: Bin<number, number>, index: number) => [
bin,
areaData[index + 1],
]);
const hoverData: [Bin<number, number>, number][] = data.bins.map(
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]]
);
// hover/tooltip
const hoverzone = svg

View File

@ -340,13 +340,9 @@ export function renderReviews(
);
}
const hoverData: [
Bin<number, number>,
number
][] = bins.map((bin: Bin<number, number>, index: number) => [
bin,
areaData[index + 1],
]);
const hoverData: [Bin<number, number>, number][] = bins.map(
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]]
);
// hover/tooltip
svg.select("g.hover-columns")

View File

@ -24,9 +24,8 @@ function showTooltipInner(msg: string, x: number, y: number): void {
tooltip.$set({ html: msg, x, y, show: true });
}
export const showTooltip: DebouncedFunc<
(msg: string, x: number, y: number) => void
> = throttle(showTooltipInner, 16);
export const showTooltip: DebouncedFunc<(msg: string, x: number, y: number) => void> =
throttle(showTooltipInner, 16);
export function hideTooltip(): void {
const tooltip = getOrCreateTooltip();

View File

@ -32,8 +32,13 @@ function allowNone(element: Element): void {
filterAttributes(() => false, element);
}
const allow = (attrs: string[]): FilterMethod => (element: Element): void =>
filterAttributes((attributeName: string) => attrs.includes(attributeName), element);
const allow =
(attrs: string[]): FilterMethod =>
(element: Element): void =>
filterAttributes(
(attributeName: string) => attrs.includes(attributeName),
element
);
function unwrapElement(element: Element): void {
element.replaceWith(...element.childNodes);
@ -88,9 +93,9 @@ const tagsAllowedExtended: TagsAllowed = {
UL: allowNone,
};
const filterElementTagsAllowed = (tagsAllowed: TagsAllowed) => (
element: Element
): void => {
const filterElementTagsAllowed =
(tagsAllowed: TagsAllowed) =>
(element: Element): void => {
const tagName = element.tagName;
if (Object.prototype.hasOwnProperty.call(tagsAllowed, tagName)) {
@ -100,7 +105,7 @@ const filterElementTagsAllowed = (tagsAllowed: TagsAllowed) => (
} else {
removeElement(element);
}
};
};
export const filterElementBasic = filterElementTagsAllowed(tagsAllowedBasic);
export const filterElementExtended = filterElementTagsAllowed(tagsAllowedExtended);

View File

@ -14,9 +14,9 @@ function iterateElement(
}
}
export const filterNode = (elementFilter: (element: Element) => void) => (
node: Node
): void => {
export const filterNode =
(elementFilter: (element: Element) => void) =>
(node: Node): void => {
switch (node.nodeType) {
case Node.COMMENT_NODE:
removeNode(node);
@ -34,4 +34,4 @@ export const filterNode = (elementFilter: (element: Element) => void) => (
default:
// do nothing
}
};
};

View File

@ -27,19 +27,20 @@ const stylingInternal: BlockProperties = [
"font-family",
];
const allowPropertiesBlockValues = (
allowBlock: AllowPropertiesBlockValues
): StylingPredicate => (property: string, value: string): boolean =>
const allowPropertiesBlockValues =
(allowBlock: AllowPropertiesBlockValues): StylingPredicate =>
(property: string, value: string): boolean =>
Object.prototype.hasOwnProperty.call(allowBlock, property) &&
!allowBlock[property].includes(value);
const blockProperties = (block: BlockProperties): StylingPredicate => (
property: string
): boolean => !block.includes(property);
const blockProperties =
(block: BlockProperties): StylingPredicate =>
(property: string): boolean =>
!block.includes(property);
const filterStyling = (predicate: (property: string, value: string) => boolean) => (
element: HTMLElement
): void => {
const filterStyling =
(predicate: (property: string, value: string) => boolean) =>
(element: HTMLElement): void => {
for (const property of [...element.style]) {
const value = element.style.getPropertyValue(property);
@ -47,7 +48,7 @@ const filterStyling = (predicate: (property: string, value: string) => boolean)
element.style.removeProperty(property);
}
}
};
};
export const filterStylingNightMode = filterStyling(
allowPropertiesBlockValues(stylingNightMode)

View File

@ -122,11 +122,11 @@ function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean {
);
}
const check = (keyCode: number, modifiers: string[]) => (
event: KeyboardEvent
): boolean => {
const check =
(keyCode: number, modifiers: string[]) =>
(event: KeyboardEvent): boolean => {
return checkKey(event, keyCode) && checkModifiers(event, modifiers);
};
};
function keyToCode(key: string): number {
return keyCodeLookup[key] || key.toUpperCase().charCodeAt(0);
@ -176,9 +176,8 @@ export function registerShortcut(
callback: (event: KeyboardEvent) => void,
keyCombinationString: string
): () => void {
const [check, ...restChecks] = splitKeyCombinationString(keyCombinationString).map(
keyCombinationToCheck
);
const [check, ...restChecks] =
splitKeyCombinationString(keyCombinationString).map(keyCombinationToCheck);
const handler = (event: KeyboardEvent): void => {
if (check(event)) {

View File

@ -108,7 +108,7 @@
"path": "node_modules/@types/lodash-es",
"licenseFile": "node_modules/@types/lodash-es/LICENSE"
},
"@types/lodash@4.14.168": {
"@types/lodash@4.14.170": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/@types/lodash",
@ -120,19 +120,19 @@
"path": "node_modules/@types/long",
"licenseFile": "node_modules/@types/long/LICENSE"
},
"@types/marked@2.0.2": {
"@types/marked@2.0.3": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/@types/marked",
"licenseFile": "node_modules/@types/marked/LICENSE"
},
"@types/node@15.0.2": {
"@types/node@15.6.1": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/protobufjs/node_modules/@types/node",
"licenseFile": "node_modules/protobufjs/node_modules/@types/node/LICENSE"
},
"bootstrap-icons@1.4.1": {
"bootstrap-icons@1.5.0": {
"licenses": "MIT",
"repository": "https://github.com/twbs/icons",
"publisher": "mdo",
@ -473,7 +473,7 @@
"path": "node_modules/long",
"licenseFile": "node_modules/long/LICENSE"
},
"marked@2.0.3": {
"marked@2.0.5": {
"licenses": "MIT",
"repository": "https://github.com/markedjs/marked",
"publisher": "Christopher Jeffrey",

View File

@ -36,8 +36,8 @@
"jsdoc": "^3.6.6",
"license-checker-rseidelsohn": "^1.2.2",
"minimist": "^1.2.5",
"prettier": "^2.1.2",
"prettier-plugin-svelte": "^1.4.0",
"prettier": "=2.3.0",
"prettier-plugin-svelte": "=2.3.0",
"sass": "^1.32.6",
"semver": "^7.3.4",
"svelte": "^3.25.0",

View File

@ -9,11 +9,13 @@ export interface DynamicSvelteComponent<
[k: string]: unknown;
}
export const dynamicComponent = <
export const dynamicComponent =
<
Comp extends typeof SvelteComponentDev,
DefaultProps = NonNullable<ConstructorParameters<Comp>[0]["props"]>
>(
>(
component: Comp
) => <Props = DefaultProps>(props: Props): DynamicSvelteComponent<Comp> & Props => {
) =>
<Props = DefaultProps>(props: Props): DynamicSvelteComponent<Comp> & Props => {
return { component, ...props };
};
};

File diff suppressed because it is too large Load Diff