summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-02-26 18:15:04 -0500
committerGitHub <noreply@github.com>2021-02-26 18:15:04 -0500
commitb994414b14b224c02359b5e31f6994653a3d4458 (patch)
tree64c28b1ea3070af7ba97b253ee3c7ba8fb114719 /ext
parent782b945905c948b9a0495aa85524ad1a92c7bd97 (diff)
Improve Anki card type selection (#1445)
* Update separator line styles * Add tabs * Add support for radio select * Remove old select * Move out of scroll region * Fix missing line
Diffstat (limited to 'ext')
-rw-r--r--ext/css/settings.css123
-rw-r--r--ext/js/pages/settings/anki-controller.js28
-rw-r--r--ext/settings.html27
3 files changed, 159 insertions, 19 deletions
diff --git a/ext/css/settings.css b/ext/css/settings.css
index 8ecaf73c..434f64a0 100644
--- a/ext/css/settings.css
+++ b/ext/css/settings.css
@@ -922,11 +922,11 @@ button.icon-button.modal-header-button>.icon-button-inner>.icon {
}
.modal-separator-line {
- border-bottom: var(--thin-border-size) solid var(--separator-color1);
+ border-top: var(--thin-border-size) solid var(--separator-color1);
margin: 0 calc(var(--modal-padding-horizontal) * -1);
}
.modal-separator-line-light {
- border-bottom: var(--thin-border-size) solid var(--separator-color2);
+ border-top: var(--thin-border-size) solid var(--separator-color2);
margin: 0 calc(var(--modal-padding-horizontal) * -1);
}
@@ -1138,6 +1138,125 @@ button.fab-button>.icon-button-inner>.icon {
}
+/* Tabs */
+.tabs-container {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: stretch;
+ margin-left: calc(-1 * var(--modal-padding-horizontal));
+ margin-right: calc(-1 * var(--modal-padding-horizontal));
+ position: relative;
+}
+.tabs {
+ flex: 1 1 auto;
+ display: flex;
+ flex-flow: row wrap;
+ align-items: stretch;
+ height: 2.75em;
+ overflow: hidden;
+}
+.tab {
+ cursor: pointer;
+ flex: 1 1 auto;
+}
+.tab>input[type='radio'] {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ display: block;
+ margin: 0;
+ padding: 0;
+ border: none;
+ appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+}
+/* TODO : Need focus/hover styles */
+.tab-inner {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ height: 100%;
+ padding: 0 1em;
+}
+.tab-inner::before {
+ content: '';
+ display: block;
+ position: absolute;
+ pointer-events: none;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: var(--text-color-light3);
+ opacity: 0;
+ transition:
+ background-color var(--animation-duration) ease-in-out,
+ opacity var(--animation-duration) ease-in-out;
+}
+.tab>input[type='radio']:checked~.tab-inner::before {
+ background-color: var(--accent-color);
+}
+.tab>input[type='radio']:hover~.tab-inner::before,
+.tab>input[type='radio']:focus~.tab-inner::before {
+ opacity: 0.125;
+}
+.tab>input[type='radio']:active~.tab-inner::before {
+ opacity: 0.25;
+}
+.tab>input[type='radio']:focus:not(:focus-visible)~.tab-inner::before {
+ opacity: 0;
+}
+.tab>input[type='radio']:focus-visible~.tab-inner::before,
+.tab>input[type='radio']:hover:focus-visible~.tab-inner::before,
+.tab>input[type='radio']:hover:not(:focus-visible)~.tab-inner::before {
+ opacity: 0.125;
+}
+.tab>input[type='radio']:active:focus-visible~.tab-inner::before,
+.tab>input[type='radio']:active:not(:focus-visible)~.tab-inner::before {
+ opacity: 0.25;
+}
+.tab-inner::after {
+ content: '';
+ display: block;
+ position: absolute;
+ pointer-events: none;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 0em;
+ background-color: var(--accent-color);
+ transition: height var(--animation-duration) ease-in-out;
+}
+.tab>input[type='radio']:checked~.tab-inner::after {
+ height: 0.2em;
+}
+.tab-label {
+ position: relative;
+ display: block;
+ font-weight: bold;
+ font-size: calc(12em / var(--font-size-no-units));
+ color: var(--text-color-light3);
+ transition: color var(--animation-duration) ease-in-out;
+}
+.tab>input[type='radio']:checked~.tab-inner>.tab-label {
+ color: var(--accent-color);
+}
+.tabs-right {
+ flex: 0 0 auto;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: center;
+ padding: 0 var(--modal-padding-horizontal);
+ height: 2.75em;
+}
+.tabs-right:not([hidden]) {
+ display: flex;
+}
+
+
/* Conditional styles */
body.sidebar-visible .content-dimmer {
visibility: visible;
diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js
index 509e263c..37ae2cf7 100644
--- a/ext/js/pages/settings/anki-controller.js
+++ b/ext/js/pages/settings/anki-controller.js
@@ -43,7 +43,6 @@ class AnkiController {
this._ankiErrorMessageDetailsToggle = null;
this._ankiErrorInvalidResponseInfo = null;
this._ankiCardPrimary = null;
- this._ankiCardPrimaryType = null;
this._validateFieldsToken = null;
}
@@ -61,13 +60,19 @@ class AnkiController {
this._ankiErrorInvalidResponseInfo = document.querySelector('#anki-error-invalid-response-info');
this._ankiEnableCheckbox = document.querySelector('[data-setting="anki.enable"]');
this._ankiCardPrimary = document.querySelector('#anki-card-primary');
- this._ankiCardPrimaryType = document.querySelector('#anki-card-primary-type');
+ const ankiCardPrimaryTypeSelect = document.querySelector('#anki-card-primary-type');
+ const ankiCardPrimaryTypeRadios = document.querySelectorAll('input[type=radio][name=anki-card-primary-type]');
this._setupFieldMenus();
this._ankiErrorMessageDetailsToggle.addEventListener('click', this._onAnkiErrorMessageDetailsToggleClick.bind(this), false);
if (this._ankiEnableCheckbox !== null) { this._ankiEnableCheckbox.addEventListener('settingChanged', this._onAnkiEnableChanged.bind(this), false); }
- if (this._ankiCardPrimaryType !== null) { this._ankiCardPrimaryType.addEventListener('change', this._onAnkiCardPrimaryTypeChange.bind(this), false); }
+ if (ankiCardPrimaryTypeSelect !== null) {
+ ankiCardPrimaryTypeSelect.addEventListener('change', this._onAnkiCardPrimaryTypeSelectChange.bind(this), false);
+ }
+ for (const input of ankiCardPrimaryTypeRadios) {
+ input.addEventListener('change', this._onAnkiCardPrimaryTypeRadioChange.bind(this), false);
+ }
const options = await this._settingsController.getOptions();
this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this));
@@ -179,8 +184,7 @@ class AnkiController {
}
}
- _onAnkiCardPrimaryTypeChange(e) {
- if (this._ankiCardPrimary === null) { return; }
+ _onAnkiCardPrimaryTypeSelectChange(e) {
const node = e.currentTarget;
let ankiCardMenu;
if (node.selectedIndex >= 0) {
@@ -188,7 +192,19 @@ class AnkiController {
ankiCardMenu = option.dataset.ankiCardMenu;
}
- this._ankiCardPrimary.dataset.ankiCardType = node.value;
+ this._setAnkiCardPrimaryType(node.value, ankiCardMenu);
+ }
+
+ _onAnkiCardPrimaryTypeRadioChange(e) {
+ const node = e.currentTarget;
+ if (!node.checked) { return; }
+
+ this._setAnkiCardPrimaryType(node.dataset.value, node.dataset.ankiCardMenu);
+ }
+
+ _setAnkiCardPrimaryType(ankiCardType, ankiCardMenu) {
+ if (this._ankiCardPrimary === null) { return; }
+ this._ankiCardPrimary.dataset.ankiCardType = ankiCardType;
if (typeof ankiCardMenu !== 'undefined') {
this._ankiCardPrimary.dataset.ankiCardMenu = ankiCardMenu;
} else {
diff --git a/ext/settings.html b/ext/settings.html
index 62117c3c..3c77b164 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -2549,20 +2549,25 @@
</div>
</div>
</div>
- <div class="modal-body anki-card" id="anki-card-primary" data-anki-card-type="terms" data-anki-card-menu="anki-card-terms-field-menu">
- <div class="settings-item"><div class="settings-item-inner">
- <div class="settings-item-left">
- <div class="settings-item-label">Card type</div>
- <div class="settings-item-description">Different types of definition can have separate settings.</div>
+ <div>
+ <div class="tabs-container">
+ <div class="tabs">
+ <label class="tab">
+ <input type="radio" name="anki-card-primary-type" data-value="terms" data-anki-card-menu="anki-card-terms-field-menu" checked>
+ <div class="tab-inner"><span class="tab-label">Terms</span></div>
+ </label>
+ <label class="tab">
+ <input type="radio" name="anki-card-primary-type" data-value="kanji" data-anki-card-menu="anki-card-kanji-field-menu">
+ <div class="tab-inner"><span class="tab-label">Kanji</span></div>
+ </label>
</div>
- <div class="settings-item-right">
- <select id="anki-card-primary-type">
- <option value="terms" data-anki-card-menu="anki-card-terms-field-menu" selected>Terms</option>
- <option value="kanji" data-anki-card-menu="anki-card-kanji-field-menu">Kanji</option>
- </select>
+ <div class="tabs-right" hidden>
+ <button class="icon-button" data-menu-position="below left" id="anki-card-primary-type-menu-button"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button>
</div>
- </div></div>
+ </div>
<div class="modal-separator-line"></div>
+ </div>
+ <div class="modal-body anki-card" id="anki-card-primary" data-anki-card-type="terms" data-anki-card-menu="anki-card-terms-field-menu">
<div class="settings-item"><div class="settings-item-inner">
<div class="settings-item-left">
<div class="settings-item-label">Deck</div>