Skip to content

Commit

Permalink
Merge pull request kintesh#109 from LoveIsGrief/preference-ui-design
Browse files Browse the repository at this point in the history
Preference ui design suggestion
  • Loading branch information
kintesh authored Oct 23, 2019
2 parents 5e24ad8 + 718ea6f commit 90bbee3
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 50 deletions.
13 changes: 8 additions & 5 deletions src/ui-preferences/BooleanPreference.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Preference from './Preference';
import {createEl, qs} from './utils';
import toggleTemplate from '!!raw-loader!./templates/toggle.html';

export default class BooleanPreference extends Preference {

Expand All @@ -7,17 +9,18 @@ export default class BooleanPreference extends Preference {
}

_buildEl() {
let el = super._buildEl();
el.type = 'checkbox';
return el;
return createEl(toggleTemplate);
}

_getCheckbox(){
return qs('.toggle__checkbox', this.el);
}
get() {
return this.el.checked;
return this._getCheckbox().checked;
}

set({value}) {
this.el.checked = !!value;
this._getCheckbox().checked = !!value;
super.set({value});
}
}
Expand Down
20 changes: 14 additions & 6 deletions src/ui-preferences/ChoicePreference.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ export default class ChoicePreference extends Preference {
_addChoices() {
for (let choice of this.choices) {
const checkedAttr = this._defaultValue === choice.name ? 'checked' : '';
this.el.appendChild(createEl(`<div class="radio-container">
<input type="radio" name="${this.name}" value="${choice.name}" ${checkedAttr}>
<label for="${this.name}">${choice.label}</label>
<div class="radio-container__description">${choice.description}</div>
</div>
`));
const $radioContainer = createEl(`<div class="radio-container">
<input type="radio" name="${this.name}" value="${choice.name}" ${checkedAttr}>
<label for="${this.name}">${choice.label}</label>
</div>
`);
if (choice.description) {
$radioContainer.appendChild(createEl(`
<info-tooltip class="radio-container__description">
${choice.description}
</info-tooltip>`
));
}
this.el.appendChild($radioContainer);
}

}

get() {
Expand Down
3 changes: 0 additions & 3 deletions src/ui-preferences/ContainerPreference.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@ export default class ContainerPreference extends PreferenceGroup {
this._preferences.push(new ChoicePreference({
name: `${name}.lifetime`,
label: 'Lifetime',
description: 'How long this container will live',
choices: [
{
'name': 'forever',
'label': 'Forever',
'description': 'Container will always be present after creation',
},
{
'name': 'untilLastTab',
'label': 'Until last tab is closed',
'description': 'Closing the last tab in the container will destroy the container',
},
],
defaultValue: 'forever',
Expand Down
19 changes: 19 additions & 0 deletions src/ui-preferences/InfoTooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import css from '!!raw-loader!./styles/InformationElement.css';
import {createEl} from './utils';

class InfoTooltip extends HTMLElement {
constructor() {
super();
let shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(createEl(`<style>${css}</style>`));
shadow.appendChild(createEl(`<span class="wrapper">
<span class="icon">i</span>
<span class="info">${this.textContent}</span>
</span>
`));

}

}

customElements.define('info-tooltip', InfoTooltip);
21 changes: 16 additions & 5 deletions src/ui-preferences/Preference.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PreferenceStorage from '../Storage/PreferenceStorage';
import preferenceContainerTemplate from '!!raw-loader!./templates/Preference.html';
import template from '!!raw-loader!./templates/Preference.html';
import {createEl, qs} from './utils';

/**
Expand All @@ -22,7 +22,9 @@ export default class Preference {
}

_buildContainerEl() {
return createEl(preferenceContainerTemplate);
const $el = createEl(this.constructor.TEMPLATE);
$el.classList.add(`pref-${this.constructor.TYPE}`);
return $el;
}

_buildEl() {
Expand All @@ -31,6 +33,13 @@ export default class Preference {
return el;
}

_addDescription($label) {
if (!this.description) {
return;
}
$label.appendChild(createEl(`<info-tooltip>${this.description}</info-tooltip>`));
}

/**
* Registers the event listeners and decides when to trigger
* an onChange event for the preference
Expand Down Expand Up @@ -85,8 +94,9 @@ export default class Preference {
* Should fill the fields in {@see $container} with initial preference attributes and add {@see el} to the container
*/
async fillContainer() {
qs('.pref-container__label', this.$container).innerHTML = this.label;
qs('.pref-container__description', this.$container).innerHTML = this.description;
const $label = qs('.preference__label', this.$container);
$label.innerHTML = this.label;
this._addDescription($label);
this._fillDocLink();

// Append the el
Expand Down Expand Up @@ -172,5 +182,6 @@ export default class Preference {

}

Preference.EL_CLASS = 'pref-container__el';
Preference.TEMPLATE = template;
Preference.EL_CLASS = 'preference__el';
Preference.TYPE = null; // Has to be set by subclass
24 changes: 15 additions & 9 deletions src/ui-preferences/PreferenceGroup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Preference from './Preference';
import {createEl, qs} from './utils';
import template from '!!raw-loader!./templates/PreferenceGroup.html';
import toggleTemplate from '!!raw-loader!./templates/toggle.html';

/**
* Groups preferences together and displays them in a manner to reflect that fact.
Expand All @@ -27,22 +28,26 @@ export default class PreferenceGroup extends Preference {
}
this._preferences = preferences;
this._toggleable = toggleable;
if(this._toggleable){
this.$container.classList.add('pref-group_toggable');
if (this._toggleable) {
this.$container.classList.add('pref-group--toggable');
}
}

_buildContainerEl() {
return createEl(template);
_buildEl() {
const $toggle = createEl(toggleTemplate);
qs('.pref-group__toggle', this.$container).appendChild($toggle);
return $toggle.querySelector('.toggle__checkbox');
}

_buildEl() {
return this.$container.querySelector(`.${PreferenceGroup.EL_CLASS}`);
_onChange(newValue) {
this.$container.classList.toggle('pref-group--active', newValue);
super._onChange(newValue);
}

async fillContainer() {
qs('.pref-group__label', this.$container).innerHTML = this.label;
qs('.pref-group__description', this.$container).innerHTML = this.description;
const $label = qs('.pref-group__label', this.$container);
$label.innerHTML = this.label;
this._addDescription($label);
this._fillDocLink();
this._createOnChange('change');
const $preferences = this.$container.querySelector('.preferences');
Expand All @@ -68,6 +73,7 @@ export default class PreferenceGroup extends Preference {
set({value}) {
if (this._toggleable) {
this.el.checked = value;
this.$container.classList.toggle('pref-group--active', value);
super.set({value});
}
}
Expand All @@ -85,5 +91,5 @@ export default class PreferenceGroup extends Preference {
}
}

PreferenceGroup.TEMPLATE = template;
PreferenceGroup.TYPE = 'group';
PreferenceGroup.EL_CLASS = 'pref-group__toggle';
2 changes: 1 addition & 1 deletion src/ui-preferences/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<script type="module" src="index.js"></script>
</head>
<body>

<h1>Preferences</h1>
<div class="preferences-container">

</div>
Expand Down
1 change: 1 addition & 0 deletions src/ui-preferences/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import './styles/index.scss';
import './index.html';
import './InfoTooltip';
import preferencesJson from './preferences.json';
import BooleanPreference from './BooleanPreference';
import ChoicePreference from './ChoicePreference';
Expand Down
9 changes: 9 additions & 0 deletions src/ui-preferences/styles/ContainerPreference.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.pref-container {
margin: 5px;
flex-grow: 1;
}

.pref-container > .preferences {
display: flex;
flex-direction: column;
}
5 changes: 5 additions & 0 deletions src/ui-preferences/styles/ContainerPreferenceGroup.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.pref-group.pref-containers > .preferences{
margin: 0;
display: flex;
flex-wrap: wrap;
}
55 changes: 55 additions & 0 deletions src/ui-preferences/styles/InformationElement.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
:host {
--size: 15px;
all: initial;
}

:host([text='']) {
display: none;
}

.wrapper {
position: relative;
display: inline-flex;
vertical-align: top;
}

.icon {
text-shadow: blue 5px 2px 5px;
position: relative;
font-style: oblique;
color: white;
border-color: white;
border-width: 1px;
border-style: solid;
background: cadetblue;
border-radius: var(--size);
line-height: var(--size);
font-size: var(--size);
width: var(--size);
height: var(--size);
text-align: center;
padding: 1px;
}


.info {
font-size: 0.8rem;
width: 200px;
display: inline-block;
border: 1px solid black;
padding: 10px;
background: black;
color: beige;
border-radius: 10px;
opacity: 0;
transition: 0.6s all;
position: absolute;
bottom: 20px;
left: 10px;
z-index: 3;
pointer-events: none;
}

.icon:hover + .info, .icon:focus + .info {
opacity: 1;
}
43 changes: 32 additions & 11 deletions src/ui-preferences/styles/index.scss
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
// BEM is used for classes
// https://en.bem.info/methodology/quick-start/
@import "toggle";
@import "ContainerPreference";
@import "ContainerPreferenceGroup";

body {
display: flex;
flex-direction: row;
flex-direction: column;
}

.pref-container {
.preference {
position: relative;
border-width: 1px;
border-radius: 3px;
border-style: dashed;
margin-bottom: 5px;
margin-top: 5px;
padding-left: 2px;
padding-right: 2px;
padding: 2px;
}

.pref-container .pref-container__label {
.preference .preference__label {
font-weight: bold;
}

.preference .pref-el-container {
display: flex;
flex-direction: column;
}

.pref-doc {
position: absolute;
right: 5px;
Expand Down Expand Up @@ -55,26 +62,40 @@ body {
padding-right: 2px;
}

.pref-group__toggle {
display: none;
.pref-group .preferences {
margin-left: 10px;
}


.pref-group__label {
font-weight: bolder;
font-size: large;
}

.pref-group_toggable .pref-group__toggle {
.pref-group__toggle {
display: none;
}

.pref-group--toggable .pref-group__toggle {
display: unset;
}

// Groups that aren't activated yet
.pref-group_toggable .pref-group__toggle ~ .preferences {
.pref-group--toggable .preferences {
opacity: 0.5;
}

.pref-group--toggable .preferences * {
pointer-events: none;
}

// Activated groups
.pref-group_toggable .pref-group__toggle:checked ~ .preferences {
opacity: unset;
.pref-group--toggable.pref-group--active .preferences * {
pointer-events: unset;
}

.pref-group--toggable.pref-group--active .preferences {
opacity: unset;
}


Loading

0 comments on commit 90bbee3

Please sign in to comment.