Skip to content

Instantly share code, notes, and snippets.

@grapho
Last active October 24, 2017 23:08
Show Gist options
  • Save grapho/4f3132c6f730bf5ecf9c54227bbd24f8 to your computer and use it in GitHub Desktop.
Save grapho/4f3132c6f730bf5ecf9c54227bbd24f8 to your computer and use it in GitHub Desktop.
Condition Slider
import Ember from 'ember';
const buildCondition = function(score, name) {
return {
condition_number: score,
condition_name: name
}
}
export const CONDITION_MAP = [
buildCondition(0, 'asset.condition.poor'),
buildCondition(25, 'asset.condition.fair'),
buildCondition(50, 'asset.condition.average'),
buildCondition(75, 'asset.condition.good'),
buildCondition(100, 'asset.condition.excellent'),
]
export default Ember.Component.extend({
classNames: ['condition-slider', 't-condition-slider'],
classNameBindings: ['computedClass'],
/**
Segments
These are defined internally for now.. eventually they may need/want to be
computed externally based on some asset metadata and passed in.
*/
segments: Ember.computed(function() {
return [...CONDITION_MAP].map((item) => {
return {
name: item.condition_name,
value: item.condition_number,
color: item.condition_name.replace(/\./g, '-')
};
});
}),
computedClass: Ember.computed('value', 'segments.[]', function() {
let value = this.get('value');
let segments = this.get('segments');
let filteredSegments = segments.filter((seg) => {
return seg.value === value;
});
return filteredSegments.get('firstObject.color') ? filteredSegments.get('firstObject.color') : null;
}),
computedSegments: Ember.computed('value', 'segments.[]', function() {
let value = this.get('value');
let segments = this.get('segments');
let mappedValues = segments.mapBy('value');
return segments.map((item, index) => {
return {
isActive: mappedValues.indexOf(value) >= index,
name: item.name,
value: item.value,
color: item.color,
}
})
}),
percentage: Ember.computed('value', function() {
let value = this.get('value') || 0;
let percentage = Math.floor((value/100)*100);
if (percentage > 100) {
percentage = 100;
} else if (percentage < 0) {
percentage = 0;
}
return percentage;
}),
flagClass: Ember.computed('percentage', function() {
let percentage = this.get('percentage');
return percentage <= 50 ? null : 'is-right';
}),
computedStyles: Ember.computed('percentage', function() {
let percentage = this.get('percentage');
if(percentage === 25) {
return {
flagPoint: Ember.String.htmlSafe('left:calc(25% - 3px);'),
};
}
if(percentage === 50) {
return {
flagPoint: Ember.String.htmlSafe('left:calc(49% - 3px);'),
};
}
if(percentage === 75) {
return {
flagPoint: Ember.String.htmlSafe('left:calc(72% - 3px);'),
};
}
if(percentage === 100) {
return {
flagPoint: Ember.String.htmlSafe('left:calc(96% - 3px);'),
};
}
})
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
condition: 75
});
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.condition-slider {
height: 5.7rem;
min-width: 12.8rem;
display: block;
display: flex;
flex-flow: column nowrap;
align-content: flex-end;
}
.bsrs-flag-container {
height: 3.2rem;
}
.bsrs-flag-track {
height: 3.2rem;
position: relative;
}
.bsrs-flag {
height: 2.5rem;
width: 4.6rem;
color: white;
text-align: center;
line-height: 2.5rem;
background: gray;
border-radius: 0.3rem;
position: relative;
}
.bsrs-flag::after {
display: block;
content: '';
width: 0;
height: 0;
border-left: 0.6rem solid transparent;
border-right: 0.6rem solid transparent;
border-top: 0.6rem solid $medGray;
position: absolute;
left: 0.1rem;
bottom: -0.5rem;
}
.bsrs-flag.is-right .bsrs-flag-content {
right: -0.6rem;
left: auto;
}
.bsrs-track-container {
height: 1rem;
//overflow: hidden;
position: relative;
}
.bsrs-main-track {
background: $darkGreen;
height: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
left: 0;
top: 0;
z-index: 2;
}
.bsrs-main-track.track-full {
width: 100%;
}
.bsrs-tick-track {
height: 1rem;
display: flex;
padding: 0 0 0 1.2rem;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 3;
}
.bsrs-track-tick {
flex: 1 0 auto;
position: relative;
height: 1rem;
pointer-events: none;
}
.bsrs-track-tick.active {
background-color: #e9e9e9;
}
.bsrs-track-tick:first-child{
min-width: 1.2rem;
position: absolute;
left: 0;
top: 0;
}
.tick-clicker {
cursor: pointer;
display: flex;
height: 3rem;
width: 3rem;
position: absolute;
right: -0.9rem;
top: -1rem;
pointer-events: auto;
}
.tick-clicker:after {
display: block;
content: '';
height: 0.6rem;
width: 0.6rem;
border-radius: 50%;
margin: auto;
background: rgba(0, 0, 0, 0.7);
}
.tick-clicker:after:hover {
height: 0.8rem;
width: 0.8rem;
}
.bsrs-track-base {
height: 1rem;
background: $light;
border: $borderStyle;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 1;
}
.bsrs-slider-labels {
display: flex;
justify-content: space-between;
color: $medGray;
font-family: $fontfamily;
font-size: 1.1rem;
@include truncate;
}
.condition-slider.asset-condition-poor .bsrs-flag,
.condition-slider.asset-condition-poor .active {
background: darkOrange;
}
.condition-slider.asset-condition-poor .bsrs-flag::after {
border-top: 0.6rem solid darkOrange;
}
.condition-slider.asset-condition-fair .bsrs-flag,
.condition-slider.asset-condition-fair .active {
background: orange;
}
.condition-slider.asset-condition-fair .bsrs-flag::after {
border-top: 0.6rem solid orange;
}
.condition-slider.asset-condition-average .bsrs-flag,
.condition-slider.asset-condition-average .active {
background: gray;
}
.condition-slider.asset-condition-average .bsrs-flag::after {
border-top: 0.6rem solid gray;
}
.condition-slider.asset-condition-good .bsrs-flag,
.condition-slider.asset-condition-good .active {
background: lightBlue;
}
.condition-slider.asset-condition-good .bsrs-flag::after {
border-top: 0.6rem solid lightBlue;
}
.condition-slider.asset-condition-excellent .bsrs-flag,
.condition-slider.asset-condition-excellent .active {
background: lightGreen;
}
.condition-slider.asset-condition-excellent .bsrs-flag::after {
border-top: 0.6rem solid lightGreen;
}
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{condition-slider
value=condition
disabled=false
update=(action (mut condition))
}}
<br>
<br>
<div class="bsrs-flag-track">
<!--div class="bsrs-flag {{flagClass}}" style={{computedStyles.flagPoint}}>
<div class="bsrs-flag-content" style={{computedStyles.flagPoint}}>{{value}}%</div>
</div-->
<div class="bsrs-flag-pointer"></div>
</div>
<div class="bsrs-track-container">
<div class="bsrs-tick-track">
{{#each computedSegments as |seg|}}
<div class="bsrs-track-tick {{if seg.isActive "active"}}">
{{#unless disabled}}
<div class="tick-clicker" onclick={{action update seg.value}}></div>
{{/unless}}
</div>
{{/each}}
</div>
<div class="bsrs-track-base"></div>
</div>
<div class="bsrs-slider-labels">
<span>Poor</span>
<span>Excellent</span>
</div>
{{log percentage}}
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0"
},
"addons": {
"ember-data": "2.12.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment