diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-02-26 18:15:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-26 18:15:04 -0500 |
commit | b994414b14b224c02359b5e31f6994653a3d4458 (patch) | |
tree | 64c28b1ea3070af7ba97b253ee3c7ba8fb114719 /ext | |
parent | 782b945905c948b9a0495aa85524ad1a92c7bd97 (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.css | 123 | ||||
-rw-r--r-- | ext/js/pages/settings/anki-controller.js | 28 | ||||
-rw-r--r-- | ext/settings.html | 27 |
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> |