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
This commit is contained in:
toasted-nutbread 2021-02-26 18:15:04 -05:00 committed by GitHub
parent 782b945905
commit b994414b14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 159 additions and 19 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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>