From 9ff1b33302b1c9feff7b502aef1d175c43fb45ae Mon Sep 17 00:00:00 2001 From: Christoph Reiter <reiter.christoph@gmail.com> Date: Tue, 13 Aug 2019 11:45:56 +0200 Subject: [PATCH] Make the language switcher a toggle button This duplicates the language switcher on the tugraz.at site. Compared to the previous implementation we now show the next language and use the translations for the next language, so that users only knowing english can understand it. In case of more languages we just cycle through them, which isn't ideal but good enough for now. --- .../src/i18n/de/translation.json | 4 +- .../src/i18n/en/translation.json | 4 +- .../language-select/src/language-select.js | 114 ++++++++++-------- packages/language-select/test/unit.js | 17 +++ 4 files changed, 87 insertions(+), 52 deletions(-) diff --git a/packages/language-select/src/i18n/de/translation.json b/packages/language-select/src/i18n/de/translation.json index 5ee4f041..62536512 100644 --- a/packages/language-select/src/i18n/de/translation.json +++ b/packages/language-select/src/i18n/de/translation.json @@ -1,4 +1,6 @@ { "de": "Deutsch", - "en": "Englisch" + "en": "Englisch", + "de-action": "Auf Deutsch anzeigen", + "en-action": "Auf Englisch anzeigen" } diff --git a/packages/language-select/src/i18n/en/translation.json b/packages/language-select/src/i18n/en/translation.json index f8615781..1177302e 100644 --- a/packages/language-select/src/i18n/en/translation.json +++ b/packages/language-select/src/i18n/en/translation.json @@ -1,4 +1,6 @@ { "de": "German", - "en": "English" + "en": "English", + "de-action": "Switch to German", + "en-action": "Switch to English" } diff --git a/packages/language-select/src/language-select.js b/packages/language-select/src/language-select.js index 53d05ed7..21d87172 100644 --- a/packages/language-select/src/language-select.js +++ b/packages/language-select/src/language-select.js @@ -9,53 +9,83 @@ class LanguageSelect extends LitElement { constructor() { super(); - this.lang = 'de'; + this._lang = 'de'; this.languages = ['de', 'en']; + this.onExternalChange = this.onExternalChange.bind(this); + + // for the i18next scanner i18n.t('de'); + i18n.t('de-action'); i18n.t('en'); + i18n.t('en-action'); + } - this.onExternalChange = this.onExternalChange.bind(this); + _getNextLanguage() { + var index = this.languages.indexOf(this.lang); + var next = this.languages[index + 1]; + if (typeof next === 'undefined') + next = this.languages[0]; + return next; } static get properties() { return { lang: {type: String}, + next: {type: String}, languages: {type: Array}, }; } + set lang(value) { + const oldValue = this.lang; + const oldNext = this.next; + this._lang = value; + this.requestUpdate('lang', oldValue); + this.requestUpdate('next', oldNext); + + if (oldValue !== value) { + const event = new CustomEvent("vpu-language-changed", { + bubbles: true, + detail: {'lang': value} + }); + this.dispatchEvent(event); + + // Unlike other cases we use the next language for the translations so that + // users not knowing the current language can understand it. + // In case of more than two this doesn't make that much sense, but for now.. + i18n.changeLanguage(this.next); + } + } + + get lang() { + return this._lang; + } + + set next(value) { + } + + get next() { + return this._getNextLanguage(); + } + static get styles() { return css` - select { - background: - linear-gradient(45deg, transparent 50%, black 50%), - linear-gradient(135deg, black 50%, transparent 50%), - linear-gradient(to right, white, white); - background-position: - calc(100% - 21px) calc(1em + 2px), - calc(100% - 16px) calc(1em + 2px), - 100% 0; - background-size: - 5px 5px, - 5px 5px, - 2.5em 2.5em; - background-repeat: no-repeat; - - border: 1px solid #000; - line-height: 1.5em; - padding: 0.5em 3.5em 0.5em 0.5em; - - border-radius: 0; - margin: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-appearance:none; - -moz-appearance:none; + a:hover { + background-color: #000; + color: #fff; + } + + a { + padding: 5px; + display: inline-block; + text-decoration: none; + color: #000; + transition: background-color 0.15s, color 0.15s; + font-weight: 300; } `; - } + } onExternalChange(e) { this.lang = e.detail.lang @@ -71,31 +101,15 @@ class LanguageSelect extends LitElement { super.disconnectedCallback(); } - update(changedProperties) { - changedProperties.forEach((oldValue, propName) => { - if (propName === 'lang') { - const event = new CustomEvent("vpu-language-changed", { - bubbles: true, - detail: {'lang': this.lang}, - }); - this.dispatchEvent(event); - - i18n.changeLanguage(this.lang); - } - }); - - super.update(changedProperties); - } - - onSelectChange(e) { - this.lang = e.target.value; + onClick(e) { + e.preventDefault(); + this.lang = this.next; } render() { + var linkTitle = i18n.t(this.next + '-action'); return html` - <select @change=${this.onSelectChange}> - ${this.languages.map(i => html`<option value="${i}" ?selected=${this.lang === i}>${i18n.t(i)}</option>`)} - </select> + <a href="#" title="${linkTitle}" @click=${this.onClick}>${this.next.toUpperCase()}</a> `; } } diff --git a/packages/language-select/test/unit.js b/packages/language-select/test/unit.js index ea01a63e..3511aa8a 100644 --- a/packages/language-select/test/unit.js +++ b/packages/language-select/test/unit.js @@ -3,8 +3,15 @@ import '../src/demo.js'; describe('vpu-language-select basics', () => { let node; + let events = []; + + function handler(e) { + events.push(e); + } beforeEach(async () => { + events.length = 0; + window.addEventListener('vpu-language-changed', handler); node = document.createElement('vpu-language-select'); document.body.appendChild(node); await node.updateComplete; @@ -12,11 +19,21 @@ describe('vpu-language-select basics', () => { afterEach(() => { node.remove(); + window.removeEventListener('vpu-language-changed', handler); }); it('should render', () => { expect(node).to.have.property('shadowRoot'); }); + + it('change language events', () => { + node.lang = 'en'; + expect(node.next).to.equal('de'); + expect(events.length).to.equal(1); + node.lang = 'de'; + expect(node.next).to.equal('en'); + expect(events.length).to.equal(2); + }); }); describe('vpu-language-select demo', () => { -- GitLab