diff options
| -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> |